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

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *