Rpi Assembler Tutorial 4
Als we de fundering leren kennen van ARM assembler, zullen de voorbeelden langer worden. Omdat bij lange programma’s het eenvoudiger word om fouten te maken is het handig dat er gewerkt word met een debugger zoals de GNU Debugger (GDB) om de assembler code te debuggen. Hier zal ik in uitleggen hoe je assembler direct debugt.
GDB
We zullen het voorbeeld store01 van deel 3 gebruiken. Start de GDB met als argumenten het programma dat je gaat debuggen
gdb --args ./store01
Nu zijn we in de interactieve mode van de GDB. Hiermee kan je commando’s uitvoeren om acties binnen de debugger uit te voeren. Er is een help command ingebouwd (gewoon help). met de quit command sluit je de debugger. Als je start typt zal je de het proces starten.
(gdb) start
Temporary breakpoint 1 at 0x8390
Starting program: /home/pi/asm/Deel3/store01
Temporary breakpoint 1, 0x00008390 in main ()
De debugger is gestopt bij de functie main. Dit is handig omdat we de eerste initialisatie stappen hebben overgeslagen. Nu is de debugger aan het wachten aan de eerste instructie van de main functie.
(gdb) disassemble Dump of assembler code for function main: => 0x00008390 : ldr r1, [pc, #40] ; 0x83c0 0x00008394 : mov r3, #3 0x00008398 : str r3, [r1] 0x0000839c : ldr r2, [pc, #32] ; 0x83c4 0x000083a0 : mov r3, #4 0x000083a4 : str r3, [r2] 0x000083a8 : ldr r1, [pc, #16] ; 0x83c0 0x000083ac : ldr r1, [r1] 0x000083b0 : ldr r2, [pc, #12] ; 0x83c4 0x000083b4 : ldr r2, [r2] 0x000083b8 : add r0, r1, r2 0x000083bc : bx lr End of assembler dump.
De instructie die naar het geheugenadres van de variabele gaat zijn anders, dit is nu nog geen probleem. de pijl => wijst naar de instructie die zal worden uitgevoerd. Voordat we deze uitvoeren laat ons de registers controleren.
(gdb) info registers r0 r1 r2 r3 r0 0x1 1 r1 0xbefff744 3204446020 r2 0xbefff74c 3204446028 r3 0x8390 33680
We kunnen de registers aanpassen met de functie p (staat voor print), maar ook de effecten zien:
(gdb) p $r0 = 2 $1 = 2 (gdb) info registers r0 r1 r2 r3 r0 0x2 2 r1 0xbefff744 3204446020 r2 0xbefff74c 3204446028 r3 0x8390 33680
De debugger heeft $1 weergegeven. Dit is het resultaat en we kunnen het gebruiken als we het nodig hebben. Nu is dit nog niet zo handig, maar bij grote programma’s zal dit nuttiger worden. Met deze command zal je de eerste instructie kunnen uitvoeren
(gdb) stepi 0x00008394 in main ()
Hier is niet veel gebeurd. Gebruik dissasemble opnieuw
(gdb) disassemble Dump of assembler code for function main: 0x00008390 : ldr r1, [pc, #40] ; 0x83c0 => 0x00008394 : mov r3, #3 0x00008398 : str r3, [r1] 0x0000839c : ldr r2, [pc, #32] ; 0x83c4 0x000083a0 : mov r3, #4 0x000083a4 : str r3, [r2] 0x000083a8 : ldr r1, [pc, #16] ; 0x83c0 0x000083ac : ldr r1, [r1] 0x000083b0 : ldr r2, [pc, #12] ; 0x83c4 0x000083b4 : ldr r2, [r2] 0x000083b8 : add r0, r1, r2 0x000083bc : bx lr End of assembler dump.
Als we kijken wat er in R1 is veranderd zullen we zien dat het het adres is voor myvar1
(gdb) info register r1 r1 0x10564 66916
Als we naar de inhoud zouden kijken van deze variabele zullen we zien dat het 0 is (wat we hadden ingesteld). Volgende stap:
(gdb) stepi 0x00008398 in main () (gdb) disas Dump of assembler code for function main: 0x00008390 : ldr r1, [pc, #40] ; 0x83c0 0x00008394 : mov r3, #3 => 0x00008398 : str r3, [r1] 0x0000839c : ldr r2, [pc, #32] ; 0x83c4 0x000083a0 : mov r3, #4 0x000083a4 : str r3, [r2] 0x000083a8 : ldr r1, [pc, #16] ; 0x83c0 0x000083ac : ldr r1, [r1] 0x000083b0 : ldr r2, [pc, #12] ; 0x83c4 0x000083b4 : ldr r2, [r2] 0x000083b8 : add r0, r1, r2 0x000083bc : bx lr End of assembler dump.
Als we kijken wat er gebeurd is met r3:
(gdb) info registers r3 r3 0x3 3
Dit is wat we verwacht hebben dus volgende stap:
(gdb) stepi 0x0000839c in main () (gdb) disas Dump of assembler code for function main: 0x00008390 : ldr r1, [pc, #40] ; 0x83c0 0x00008394 : mov r3, #3 0x00008398 : str r3, [r1] => 0x0000839c : ldr r2, [pc, #32] ; 0x83c4 0x000083a0 : mov r3, #4 0x000083a4 : str r3, [r2] 0x000083a8 : ldr r1, [pc, #16] ; 0x83c0 0x000083ac : ldr r1, [r1] 0x000083b0 : ldr r2, [pc, #12] ; 0x83c4 0x000083b4 : ldr r2, [r2] 0x000083b8 : add r0, r1, r2 0x000083bc : bx lr End of assembler dump.
Als we nu naar het einde gaan:
(gdb) continue Continuing. [Inferior 1 (process 3080) exited with code 07]
Nu zien we dat het heeft gestopt met code 07, wat het resultaat is!
Dit was alles voor deel 4