L1VM - assembly VOL III

Here I will show how function calls are done in assembly.

Here is the Brackets program:

// square-func.l1com
//
// calculate square of number
//
#include <intr.l1h>
(main func)
    (set int64 1 zero 0)
    (set double 1 a 2.0)
    (set double 1 b 13.5)
    (set double 1 c 7.8)
    (set double 1 as 0.0)
    (set double 1 bs 0.0)
    (set double 1 cs 0.0)

    // call square functions with numbers a, b and c:
    (a :square !)
    (as stpopd)
    print_d (as)
    print_n

    (b :square !)
    (bs stpopd)
    print_d (bs)
    print_n

    (c :square !)
    (cs stpopd)
    print_d (cs)
    print_n

    exit (zero)
(funcend)

(square func)
    (set double 1 num 0.0)
    (set double 1 square 0.0)
    (num stpopd)
    {square = num num *}
    (square stpushd)
(funcend)

Lets have a look at:

 // call square functions with numbers a, b and c:
    (a :square !)
    (as stpopd)
    print_d (as)
    print_n

Here is the assemby output:

:main
loada zero, 0, 0
stpushi 0
loadd a, 0, 1
stpushd 1
jsr :square
stpopd 2
load as, 0, 3
pulld 2, 3, 0
stpopi 0
loadd as, 0, 1
intr0 5, 1, 0, 0
intr0 7, 0, 0, 0

Here the “loadd a, 0, 1” opcode loads the double variable “a” into register “1”. Then with “stpushd 1” the register “1” is put on the stack. We need this for the function call: “jsr: square”. After the function call we need to get the result from the stack: “stpopd 2”. Then the result is stored into variable “as”:

load as, 0, 3
pulld 2, 3, 0

Now I will show the function “square”:

(square func)
    (set double 1 num 0.0)
    (set double 1 square 0.0)
    (num stpopd)
    {square = num num *}
    (square stpushd)
(funcend)

The assembly looks like this:

:square
loada zero, 0, 0
stpopd 1
load num, 0, 2
pulld 1, 2, 0
muld 1, 1, 2
load square, 0, 3
pulld 2, 3, 0
loadd square, 0, 2
stpushd 2
rts

The “stpopd 1” gets the double number from the stack. The “muld 1, 1, 2” multiplies the number with it self and stores the result in register “2”.

Then the result register is stored into variable “square”:

load square, 0, 3
pulld 2, 3, 0

The last step pushes the variable “square” to the stack:

loadd square, 0, 2
stpushd 2

The function jumps back to the caller by:

rts

That is it! Have some fun!

15: assembly VOL IV