ARM Assembly

ARM Debugging Loops Part 3
We want to iterate through our loop, but we don't want to manually step through every instruction over and over again. We can automate this process by using another script. First, we will set a break point at the end of our loop with:
(gdb) break *0x100c0
Breakpoint 1 at 0x100c0
The * character lets gdb know that the value is a memory address and not a label name.
Enter:
continue
To skip down to our break point. Now we can write our script. Enter:
(gdb) set $count = 0
(gdb) while $count < 8
>source cpsr_cmp.gdb
>continue 
>set $count = $count +1 
>end
We just wrote a while loop to debug our while loop.

Your output should be similar to this (note you may have to enter ctrl + l to re-draw your screen):
|-Register group: general------------------------------------------------------------------------------------------------------------------------------------------------|
|r0             0x2                 2                                                r1             0x408009bc          1082132924                                       |
|r2             0x2                 2                                                r3             0x9                 9                                                |
|r4             0x0                 0                                                r5             0x0                 0                                                |
|r6             0x0                 0                                                r7             0x4                 4                                                |
|r8             0x0                 0                                                r9             0x0                 0                                                |
|r10            0x200ec             131308                                           r11            0x0                 0                                                |
|r12            0x0                 0                                                sp             0x408009c0          0x408009c0                                       |
|lr             0x0                 0                                                pc             0x100c0             0x100c0 <print_counter+52>                       |
|cpsr           0x80000010          -2147483632                                      fpscr          0x0                 0                                                |
|fpsid          0x410430f0          1090793712                                       fpexc          0x40000000          1073741824                                       |
|AFSR0_EL1      0x0                 0                                                AFSR1_EL1      0x0                 0                                                |
|DBGDIDR        0x3515f021          890630177                                        DBGDSAR        0x0                 0                                                |
|DBGBVR         0x0                 0                                                DBGBCR         0x0                 0                                                |
|DBGWVR         0x0                 0                                                DBGWCR         0x0                 0                                                |
|PAR            0x0                 0                                                DBGBVR         0x0                 0                                                |
|DBGBCR         0x0                 0                                                DBGWVR         0x0                 0                                                |
|DBGWCR         0x0                 0                                                TEECR          0x0                 0                                                |
|MIDR_EL1       0x412fc0f1          1093648625                                       CTR            0x8444c004          -2075869180                                      |
|TCMTR          0x0                 0                                                TTBR0_EL1      0x0                 0                                                |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|    0x10098 <print_counter+12>      add     r1, r1, r3                                                                                                                  |
|    0x1009c <print_counter+16>      orr     r1, r1, #2560   ; 0xa00                                                                                                     |
|    0x100a0 <print_counter+20>      push    {r1}            ; (str r1, [sp, #-4]!)                                                                                      |
|    0x100a4 <print_counter+24>      mov     r1, sp                                                                                                                      |
|    0x100a8 <print_counter+28>      mov     r2, #2                                                                                                                      |
|    0x100ac <print_counter+32>      svc     0x00000000                                                                                                                  |
|    0x100b0 <print_counter+36>      add     sp, sp, #4                                                                                                                  |
|    0x100b4 <print_counter+40>      cmp     r3, #9                                                                                                                      |
|    0x100b8 <print_counter+44>      bge     0x100c4 <print_end_msg>                                                                                                     |
|    0x100bc <print_counter+48>      add     r3, r3, #1                                                                                                                  |
|B+> 0x100c0 <print_counter+52>      b       0x1008c <print_counter>                                                                                                     |
|    0x100c4 <print_end_msg>         mov     r7, #4                                                                                                                      |
|    0x100c8 <print_end_msg+4>       mov     r0, #1                                                                                                                      |
|    0x100cc <print_end_msg+8>       ldr     r1, [pc, #20]   ; 0x100e8 <exit_normally+16>                                                                                |
|    0x100d0 <print_end_msg+12>      mov     r2, #12                                                                                                                     |
|    0x100d4 <print_end_msg+16>      svc     0x00000000                                                                                                                  |
|    0x100d8 <exit_normally>         mov     r7, #1                                                                                                                      |
|    0x100dc <exit_normally+4>       mov     r0, #0                                                                                                                      |
|    0x100e0 <exit_normally+8>       svc     0x00000000                                                                                                                  |
|    0x100e4 <exit_normally+12>      andeq   r0, r2, r12, ror #1                                                                                                         |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
remote Thread 1.39901 In: print_counter                                                                                                                 L??   PC: 0x100c0
N=1 Z=0 C=0 V=0

Breakpoint 1, 0x000100c0 in print_counter ()
N=1 Z=0 C=0 V=0

Breakpoint 1, 0x000100c0 in print_counter ()
N=1 Z=0 C=0 V=0

Breakpoint 1, 0x000100c0 in print_counter ()
N=1 Z=0 C=0 V=0

Breakpoint 1, 0x000100c0 in print_counter ()
N=1 Z=0 C=0 V=0

Breakpoint 1, 0x000100c0 in print_counter ()
N=1 Z=0 C=0 V=0

Breakpoint 1, 0x000100c0 in print_counter ()
N=1 Z=0 C=0 V=0

Breakpoint 1, 0x000100c0 in print_counter ()
(gdb)
Notice we are now on what should be the last iteration of the loop. Let's advance to the bge instruction with:
advance *0x100b8
Let's look at what flags were set with our cmp instruction:
(gdb) source cpsr_cmp.gdb
N=0 Z=1 C=1 V=0
Notice that the zero bit is now set and the negative bit is no longer set.

The zero bit is set because r3 was equal to 9. The negative bit is not set because the result of 9 - 9 isn't negative. Both of these condititions should cause our branch condition to be met.

Let's test this branch by setting a break point where we should jump to:
(gdb) break *0x100c4
Breakpoint 2 at 0x100c4
Enter continue to advance the program to the next break:
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|    0x1008c <print_counter>         mov     r7, #4                                                                                                                      |
|    0x10090 <print_counter+4>       mov     r0, #1                                                                                                                      |
|    0x10094 <print_counter+8>       mov     r1, #48 ; 0x30                                                                                                              |
|    0x10098 <print_counter+12>      add     r1, r1, r3                                                                                                                  |
|    0x1009c <print_counter+16>      orr     r1, r1, #2560   ; 0xa00                                                                                                     |
|    0x100a0 <print_counter+20>      push    {r1}            ; (str r1, [sp, #-4]!)                                                                                      |
|    0x100a4 <print_counter+24>      mov     r1, sp                                                                                                                      |
|    0x100a8 <print_counter+28>      mov     r2, #2                                                                                                                      |
|    0x100ac <print_counter+32>      svc     0x00000000                                                                                                                  |
|    0x100b0 <print_counter+36>      add     sp, sp, #4                                                                                                                  |
|    0x100b4 <print_counter+40>      cmp     r3, #9                                                                                                                      |
|    0x100b8 <print_counter+44>      bge     0x100c4 <print_end_msg>                                                                                                     |
|    0x100bc <print_counter+48>      add     r3, r3, #1                                                                                                                  |
|B+  0x100c0 <print_counter+52>      b       0x1008c <print_counter>                                                                                                     |
|B+> 0x100c4 <print_end_msg>         mov     r7, #4                                                                                                                      |
|    0x100c8 <print_end_msg+4>       mov     r0, #1                                                                                                                      |
|    0x100cc <print_end_msg+8>       ldr     r1, [pc, #20]   ; 0x100e8 <exit_normally+16>                                                                                |
|    0x100d0 <print_end_msg+12>      mov     r2, #12                                                                                                                     |
|    0x100d4 <print_end_msg+16>      svc     0x00000000                                                                                                                  |
|    0x100d8 <exit_normally>         mov     r7, #1                                                                                                                      |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
remote Thread 1.40929 In: print_end_msg                                                                                                                 L??   PC: 0x100c4
N=1 Z=0 C=0 V=0

Breakpoint 1, 0x000100c0 in print_counter ()
N=1 Z=0 C=0 V=0

Breakpoint 1, 0x000100c0 in print_counter ()
N=1 Z=0 C=0 V=0

Breakpoint 1, 0x000100c0 in print_counter ()
(gdb) si
0x0001008c in print_counter ()
(gdb) advance *0x100b8
0x000100b8 in print_counter ()
(gdb) source cpsr_cmp.gdb
N=0 Z=1 C=1 V=0
(gdb) break *0x100c4
Breakpoint 2 at 0x100c4
(gdb) continue
Continuing.

Breakpoint 2, 0x000100c4 in print_end_msg ()
(gdb)
Notice that our program had two breakpoints set, one at 0x100c0 which would branch back to the start of our loop, and another at 0x100c4 which will continue the rest of the program. Our condition to branch was met by both the zero bit being set to 1 and the negative bit being set to 0, so execution moved to 0x100c4.
Enter continue one last time to finish executing the remainder of the program:
	(gdb) continue
	Continuing.
	[Inferior 1 (process 1) exited normally]
	(gdb)
ARM Loop Exercises

Exercise 1.

Find the other flag bit that is set in the cpsr. Why is it set?

Exercise 2.

Write a gdb script that prints all of the cpsr flags in the format of the cpsr_cmp script.

Exercise 3:

Re-write the loop to allow for more than 10 iterations while printing the correct iteration number.