Wat gaan we doen? Herhaling ARM assembler instructies Branch instructie Subroutines, gebruik van de stack Conditionele instructies en de flags Oefening
LDR R0, =value registers geheugen R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R13 = SP R14 = LR R15 = PC 0000 0000 0000 0001 0000 0002 0000 0003 0000 0004 0000 0005 0000 0006 0000 0007 0000 0008 0000 0009 ……. FFFF FFFB FFFF FFFC FFFF FFFD FFFF FFFE FFFF FFFF registers geheugen
MOV R0, R1 registers geheugen R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R13 = SP R14 = LR R15 = PC 0000 0000 0000 0001 0000 0002 0000 0003 0000 0004 0000 0005 0000 0006 0000 0007 0000 0008 0000 0009 ……. FFFF FFFB FFFF FFFC FFFF FFFD FFFF FFFE FFFF FFFF registers geheugen
LDR R0, [ R1 ] registers geheugen R0 R1 000 0004 R2 R3 R4 R5 R6 R7 R8 R13 = SP R14 = LR R15 = PC 0000 0000 0000 0001 0000 0002 0000 0003 0000 0004 0000 0005 0000 0006 0000 0007 0000 0008 0000 0009 ……. FFFF FFFB FFFF FFFC FFFF FFFD FFFF FFFE FFFF FFFF registers geheugen
STR R0, [ R1 ] registers geheugen R0 R1 FFFF FFFC R2 R3 R4 R5 R6 R7 R8 R13 = SP R14 = LR R15 = PC 0000 0000 0000 0001 0000 0002 0000 0003 0000 0004 0000 0005 0000 0006 0000 0007 0000 0008 0000 0009 ……. FFFF FFFB FFFF FFFC FFFF FFFD FFFF FFFE FFFF FFFF registers geheugen
ADD R3, R1, R2 + registers geheugen R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R13 = SP R14 = LR R15 = PC 0000 0000 0000 0001 0000 0002 0000 0003 0000 0004 0000 0005 0000 0006 0000 0007 0000 0008 0000 0009 ……. FFFF FFFB FFFF FFFC FFFF FFFD FFFF FFFE FFFF FFFF + registers geheugen
Drie getallen optellen .global main getal_1 : .word 11 getal_2 : .word 22 getal_3 : .word 33 som : .word 99999 main: ldr r0, =0 ldr r1, =getal_1 ldr r2, [ r1 ] add r0, r0, r2 ldr r1, =getal_2 ldr r1, =getal_3 add r0, r0, r2 ldr r1, =som str r0, [ r1] done: b done
B = branch registers geheugen R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R13 = SP R14 = LR R15 = PC 0000 0000 0000 0001 0000 0002 0000 0003 0000 0004 0000 0005 0000 0006 0000 0007 0000 0008 0000 0009 ……. FFFF FFFB FFFF FFFC FFFF FFFD FFFF FFFE FFFF FFFF registers geheugen
BL = branch and link registers geheugen R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R13 = SP R14 = LR R15 = PC 0000 0000 0000 0001 0000 0002 0000 0003 0000 0004 0000 0005 0000 0006 0000 0007 0000 0008 0000 0009 ……. FFFF FFFB FFFF FFFC FFFF FFFD FFFF FFFE FFFF FFFF registers geheugen
Een subroutine aanroepen . return Hoofdprogramma . Call sub
Een subroutine aanroepen . return Hoofdprogramma . call sub
ARM subroutine mechanisme . MOV PC, LR Hoofdprogramma . BL SUB BL label R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 = SP R14 = LR R15 = PC registers
Een subroutine gebruiken (1) .global main getal_1 : .word 11 getal_2 : .word 22 getal_3 : .word 33 som : .word 99999 add: ldr r2, [ r1 ] add r0, r0, r2 mov PC, LR main: ldr r0, =0 ldr r1, =getal_1 bl add ldr r1, =getal_2 ldr r1, =getal_3 ldr r1, =som str r0, [ r1] done: b done Een subroutine gebruiken (1)
Een subroutine gebruiken (2) .global main getal_1 : .word 11 getal_2 : .word 22 getal_3 : .word 33 som : .word 99999 add: ldr r2, [ r1 ] add r1, r1, #4 add r0, r0, r2 mov PC, LR main: ldr r0, =0 ldr r1, =getal_1 bl add ldr r1, =som str r0, [ r1] done: b done Een subroutine gebruiken (2) add: ldr r2, [ r1 ] add r0, r0, r2 mov PC, LR main: ldr r0, =0 ldr r1, =getal_1 bl add ldr r1, =getal_2 ldr r1, =getal_3 ldr r1, =som
Een subroutine roept een andere subroutine aan. .global main getal_1 : .word 11 getal_2 : .word 22 getal_3 : .word 33 som : .word 99999 add_r0_r2: add r0, r0, r2 mov PC, LR add: ldr r2, [ r1 ] BL add_r0_r2 add r1, r1, #4 mov pc, lr main: ldr r0, =0 ldr r1, =getal_1 bl add ldr r1, =som str r0, [ r1] ….. Een subroutine roept een andere subroutine aan. Wat gaat hier mis?
Stack A stack is an area of memory which grows as new data is “pushed” onto the “top” of it, and shrinks as data is “popped” off the top. stack pointer used to point the current “top” of the stack. empty ascending / empty decending / full ascending / full decenuing PUSH {1,2,3} POP 1 2 3 Result of pop = 3 SP 2 1 SP
assembler instructie formaat : multiple words van en naar geheugen (block transfer instructies) STMFD SP!, { R1-R9, R12 } LDMFD SP!, { R1-R9, R12 }
Gebruik de stack subroutine: stmfd sp!, { r2, r3, r4, lr } … ldmfd sp!, { pc, r2-r4 }
Gebruik de stack add_r0_r2: add r0, r0, r2 mov PC, LR add1: .global main getal_1 : .word 11 getal_2 : .word 22 getal_3 : .word 33 som : .word 99999 add_r0_r2: stmfd sp!, { lr } add r0, r0, r2 ldmfd sp!, { pc } add1: stmfd sp!, { r2, lr } ldr r2, [ r1 ] bl add_r0_r2 add r1, r1, #4 ldmfd sp!, { r2, pc } main: ldr r0, =0 ldr r1, =getal_1 bl addl ldr r1, =som str r0, [ r1] ….. Gebruik de stack add_r0_r2: add r0, r0, r2 mov PC, LR add1: ldr r2, [ r1 ] BL add_r0_r2 add r1, r1, #4 mov pc, lr
ARM instructie set iedere instructie is conditioneel Bijna alle instructies kunnen de conditie flags zetten ”de conditie” is de uitkomst van de laatste rekeninstructie die de flags heeft gezet (S achtervoegsel)
The ARM condition code field All instructions are conditionally executed!
Conditions
Zet de flags of laat ze ongewijzigd Gewoon een S (= Set Condition Codes) achter de instructie ADDS r0, r1, r2 @ zet de flags ADC r3, r4, r5 @ laat de flags ongewijzig (carry!)
2 getallen vergelijken R0 == a, R1 == b, R2 == n subs r3, r0, r1 bne niet_verhogen add r2, r2, #1 niet_verhogen: if ( a == b ){ n++; } R0 == a, R1 == b, R2 == n subs r3, r0, r1 addeq r2, r2, #1 niet_verhogen:
De grootste selecteren R0 == a, R1 == b, R2 == g subs r3, r0, r1 blt else mov r2, r0 b klaar else: mov r2, r1 klaar: if ( a > b ){ g = a; } else { g = b; } R0 == a, R1 == b, R2 == g subs r3, r0, r1 movgt r2, r0 movle r2, r1
Hier zelf code toevoegen Drie getallen optellen in een loop .global main getal_1 : .word 11 getal_2 : .word 22 getal_3 : .word 33 som : .word 0 main: ldr r0, =0 @ initialisatie loop: @ loop body subs r2, r2, #1 bne loop ldr r1, =som str r0, [ r1] done: b done Hier zelf code toevoegen
Opdrachten: 1. Maak zelf het ‘loop’ optel programma af en test het Opdrachten: 1. Maak zelf het ‘loop’ optel programma af en test het. Hierbij hoef je geen subroutine te gebruiken. 2. maak (en test) een nette subroutine die 2 getallen vermenigvuldigt (door herhaald optellen). Het is misschien handig eerst in C te schrijven hoe je dit zou doen.