ARM Assembly

ARM Debugging Loops Part 2
Let's step into our instructions from here and examine the orr instruction at 0x1009c:
|-Register group: general------------------------------------------------------------------------------------------------------------------------------------------------|
|r0             0x1                 1                                                r1             0x30                48                                               |
|r2             0x15                21                                               r3             0x0                 0                                                |
|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             0x1009c             0x1009c <print_counter+16>                       |
|cpsr           0x10                16                                               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                                                |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|    0x10074 <_start>                mov     r7, #4                                                                                                                      |
|    0x10078 <_start+4>              mov     r0, #1                                                                                                                      |
|    0x1007c <_start+8>              ldr     r1, [pc, #96]   ; 0x100e4 <exit_normally+12>                                                                                |
|    0x10080 <_start+12>             mov     r2, #21                                                                                                                     |
|    0x10084 <_start+16>             svc     0x00000000                                                                                                                  |
|    0x10088 <_start+20>             mov     r3, #0                                                                                                                      |
|    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                                                                                                     |
As we step through the instruction we can see that the value of r1 changes from 0x30 to 0x0a30. It now contains the value for ASCII "0\n"
r1             0xa30               2608                 
Now lets step to the push instruction:
|-Register group: general------------------------------------------------------------------------------------------------------------------------------------------------|
|r0             0x1                 1                    r1             0xa30               2608                 r2             0x15                21                   |
|r3             0x0                 0                    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             0x100a0             0x100a0 <print_count cpsr           0x10                16                   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                    PMCCNTR        0x0                 0                    |
|TLBTR          0x0                 0                    TTBR1_EL1      0x0                 0                    MIDR           0x412fc0f1          1093648625           |
|TTBCR          0x0                 0                    MPIDR_EL1      0x80000000          -2147483648          TTBCR2         0x0                 0                    |
|REVIDR_EL1     0x0                 0                    MIDR           0x412fc0f1          1093648625           JIDR           0x0                 0                    |
|CLIDR          0xa200023           169869347            DFAR           0x0                 0                    WFAR           0x0                 0                    |
|IFAR           0x0                 0                    JMCR           0x0                 0                    AIDR           0x0                 0                    |
|CSSELR         0x0                 0                    ID_PFR2        0x10                16                   VBAR           0x0                 0                    |
|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|    0x10074 <_start>                mov     r7, #4                                                                                                                      |
|    0x10078 <_start+4>              mov     r0, #1                                                                                                                      |
|    0x1007c <_start+8>              ldr     r1, [pc, #96]   ; 0x100e4 <exit_normally+12>                                                                                |
|    0x10080 <_start+12>             mov     r2, #21                                                                                                                     |
|    0x10084 <_start+16>             svc     0x00000000                                                                                                                  |
|    0x10088 <_start+20>             mov     r3, #0                                                                                                                      |
|    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]!)                                                                                      |  
Notice the value of the sp register before the push:
sp             0x408009c0
Now after the push:
sp             0x408009bc
This is 4 bytes lower than the previous address. Lets examine the data at that address:
(gdb) x /4xb 0x408009bc
0x408009bc:     0x30    0x0a    0x00    0x00  
We can see the value of r1 is now at that address.
The instruction mov r1, sp will store that address in r1 to pass to the write syscall.

Let's now examine the cmp instruction at 0x100b4:
> 0x100b4 <print_counter+40>      cmp     r3, #9
(gdb) info registers cpsr
cpsr           0x10                16
(gdb) si
0x000100b8 in print_counter ()
(gdb) info registers cpsr
cpsr           0x80000010          -2147483632
As we step through the instruction, we can see the value of the flags in cpsr change.

What flags are now set? We could print the value in binary with:
(gdb) print/t 0x80000010
$1 = 10000000000000000000000000010000
This is still difficult to read and determine what flags are set.

We know that the Z, N, C, and V flags are set by the cmp instruction, so let's format the output to show those flags.
Enter the following script to show a formatted output for the flags:
printf "N=%d Z=%d C=%d V=%d\n", (($cpsr & (1 << 31)) != 0), (($cpsr & (1 << 30)) != 0), (($cpsr & (1 << 29)) != 0), (($cpsr & (1 << 28)) != 0)
This is a script in C-style code which takes the cpsr register value performs a bitwise and operation on a bit that is shifted left to the position of the corresponding flag bit, if the bit is set, the statement will be non-zero and evaluate true, which will print a 1.

We can see from this script that the negative bit was set by the comparison, because 0 - 9 = -9 which is negative.
N=1 Z=0 C=0 V=0
This would be lengthy to type out every time we want to check those flags, so lets open a text editor and save the script as cpsr_cmp.gdb
We can now run the script inside gdb by entering:
source cpsr_cmp.gdb  
This is assuming you placed it in the same path as the current executable.
Otherwise you must use the path to the script.