L1VM - course 08

arrays

Here I will show some array handling code.

This defines an int64 (64 bit int number) array with 10 elements:

(set int64 10 array 10 5 8 4 3 2 7 23 45 30)

To access the array elements we need an index and an offset:

((ind offset *) realind =)
(array [ realind ] num =)

The first line calculates the offset and stores the result in “realind”. We are accessing an int64 number in the array: the offset is “8”! On a byte array this offset would be “1” and we would not need it! This offset is needed because internally every variable is stored in a simple byte array! You can see this by looking at an assembly file generated by the compiler (.l1asm).

The VM can find illegal array accesses and breaks the program execution. You will get an error message.

If we set the max number of elements to read to “11” then we get this error message:

l1vm-work]$ l1vm prog/array-demo -q
10
5
8
4
3
2
7
23
45
30
memory_bounds: FATAL ERROR: variable not found overflow address: 56, offset: 80!
epos: 231

In the assembly file we find address “56” in line 16: “@, 56Q”.

Q, 10, array
@, 56Q, 10, 5, 8, 4, 3, 2, 7, 23, 45, 30, ;

On the address “56” the array “array” is stored! Here the offset is out of range!

The “epos” is the execution position of the current opcode. We can find it in the “out.l1dbg” file:

In line “19”:

epos: 231, 41 line num

This shows the line in the assembly source code: lines 38 - 41:

loada num, 0, 9
loada realind, 0, 10
load array, 0, 11
pushqw 11, 10, 9

So here we see the opcode in line 41:

pushqw 11, 10, 9

In line 40 the array address is load into the register “11” and the “realind” variable into register “10”. So we found the line with the error in it! This is not easy to find but it is possible. You can also take a look at the assembly file output of the Brackets compiler to learn more about the assembly code!

Here is the full array demo program:

// array-demo.l1com
// array with values demo
// shows how to set up an array
// and how to access the elements
//
#include <intr.l1h>
(main func)
	(set int64 1 zero 0)
    (set int64 1 one 1)
	(set const-int64 1 offset 8)
    (set int64 1 ind 0)
    (set int64 1 f 0)
    (set int64 1 num 0)
    (set int64 1 realind 0)
	// set array data using spaces as elements separator
	(set int64 10 array 10 5 8 4 3 2 7 23 45 30)
    (set int64 1 maxarray 10)
    // print array 
    (for-loop)
    (((ind maxarray <) f =) f for)
        ((ind offset *) realind =)
        (array [ realind ] num =)
        print_i (num)
        print_n
        ((ind one +) ind =)
    (next)
	exit (zero)
(funcend)

Now we get this output:

$ l1vm prog/array-demo -q
10
5
8
4
3
2
7
23
45
30

And everything runs just fine!

To store a number in the array, we can do:

(num array [ realind ] =)

9: logical operators, bit shifting