Friday, 21 June 2013

Using indexed memory locations

.equ datum_size,1
.globl main
.align 2
.section .rodata
output:
 .asciz "The value is %d\n"
values:
 .byte 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60
endvalues:
.align 2
.text
main:
 stmfd sp!, {r5, r6, lr}       @ save the registers we use to the stack
 ldr r5, =endvalues
 ldr r6, =values
loop:
 ldrb r1, [r6], #datum_size    @ r6 will be implicitly incremented so r1 will contain each element in turn
 ldr r0, =output               @ the address of the string is put in r0
 bl  printf                    @ we print the value of r1 in the string pointed to by r0
 cmp r6, r5                    @ have we reached the endvalues label?
 bne loop                      @ if not, read and print the next element

 ldmfd sp!, {r4, r5, r6, pc}   @ restore registers before exit
 mov     r7, #1                @ set r7 to 1 - the syscall for exit
 swi     0                     @ then invoke the syscall from linux


Here the .equ directive is introduced which aliases a value to a name.

We do so because we can easily change from using bytes for storage of the value to using half-words (of 2 bytes) or words (of 4 bytes) in the data section and modification of the ldrb instruction to ldrh or ldr respectively.

bob@poland:~/www/examples$ make movtest3
/usr/bin/gcc -gstabs -o movtest3 movtest3.s
bob@poland:~/www/examples$ ./movtest3
The value is 10
The value is 15
The value is 20
The value is 25
The value is 30
The value is 35
The value is 40
The value is 45
The value is 50
The value is 55
The value is 60
bob@poland:~/www/examples$

Again we use gcc rather than as to assemble since we use the C function, printf.

No comments:

Post a Comment