Running Assembly Code Through the debugger

There are two basic ways to inspect a running program: print out a bunch of debug statements or run it through a debugger. Since I don’t yet know how to print out my own statements in ARM64 debugging (I’ll get there soon) I want to use the debugger to see my code in action.

First, a little tweak to the Makefile rule to build the code. I hard code in the -g flag to include debugging symbols in the executables. This is learning code, and I am not going to be running it in stripped mode, so no need for Makefile variables.

%: %.s 
	as -g -o $@.o $<
	ld -o $@ $@.o

I’ve got a simple assembly program that adds the value and 2 together. It looks like this:

.global _start
            MOV   W0, #2
            ADD   W0, W0, #1
            MOV     X8, #93
            SVC     0

Compile it:

$ make adder
as -g -o adder.o adder.s
ld -o adder adder.o

OK, let’s fire up the assembler. Here’s the start of the session slightly edited

$ gdb adder
GNU gdb (GDB) Fedora 11.1-2.fc34
Reading symbols from adder...
(gdb) list
1	.global _start
3	_start:     
4	            MOV   W0, #2
5	            ADD   W0, W0, #1
8	            MOV     X8, #93
9	            SVC     0
(gdb) break _start
Breakpoint 1 at 0x400078: file adder.s, line 4.
(gdb) run
Starting program: /home/ayoung/devel/asm/adder 
Breakpoint 1, _start () at adder.s:4
4	            MOV   W0, #2

Now we are at the start of the program, on the first line of code. It has not yet been executed. What is the pre-value of the W0 register?

(gdb) i r w0
w0             0x0                 0

Now make single step, and we should be able to see the value get stored in the register. The following step shows the addition. The final step shows the completion of the program

(gdb) n
5	            ADD   W0, W0, #1
(gdb) i r w0
w0             0x2                 2
(gdb) n
8	            MOV     X8, #93
(gdb) i r w0
w0             0x3                 3
(gdb) n
9	            SVC     0
(gdb) step
[Inferior 1 (process 608616) exited with code 03]

Note that I used n for next in most cases, but I used step in the last. Why? I wanted to see if I could follow the function call (I couldn’t) when I called svc 0. In C code, the next command will skip over function calls, but the step command will step into them. In this case, they behaved the same

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.