ARMv8 Assembly and GDB
PhD Student
Fall 2017
General formatting rules for this course:
// File: example.s
// Author: Joshua Horacsek
// Date: September 25th, 2017
//
// Description:
// This should describe what the program accomplishes
main: mov x0, 1 // Set x0 to 1
mov x1, x0 // copy x0 into x1
add x1, x1, x0 // add the two numbers
General formatting rules for this course:
add x1, x1, x0 // add x1 and x2, which computes a
// fibonnaci sum, and store that in x1
Hello world in assembly
// File: helloworld.s
// Author: Joshua Horacsek
// Date: September 25th, 2017
//
// Description:
// Prints "Hello World!" using printf in assembly
hello_world_str: .string "Hello World\n" // This creates a label and defines the string "Hello World"
// in memory
.balign 4 // Makes sure the following instruction's address is
// divisible by 4, i.e. aligned to the word length of
// the machine
.global main // Enusre that the "main" label is visible to the linker
main:
stp x29, x30, [sp, -16]! // Save FP and LR to the stack
mov x29, sp // Set FP to the stack addr
adrp x0, hello_world_str // This line and the next set the first agument to printf
add x0, x0, :lo12:hello_world_str
bl printf // Call printf
ldp x29, x30, [sp], 16 // Restore the stack
ret // return to OS
Compiling
gcc helloworld.s -o helloworld
This is very similar to compiling your C code
At some point in the future, we will be mixing C and assembly.
Registers keep track of results and store data:
Only ever expect x19-x28 to be saved after you call a function, the rest may be trashed
MOV: Move data into or between registers
mov xd, #imm64
xd = #imm64
mov wd, #imm32
wd = #imm32 // only the lower 32 bits
mov xd, xn
xd = xn
mov wd, wn
wd = wn // only the lower 32 bits
ADD: Adds two operands and stores them in a register
add xd, xn, #imm64
xd = xn + #imm64
add xd, xn, xm
xd = xn + xm
SUB: Subtracts two operands and stores them in a register
sub xd, xn, #imm64
xd = xn - #imm64
sub xd, xn, xm
xd = xn - xm
MUL: Multiply operands, stores the result in a register
mul xd, xn, xm
xd = xm * xn
MADD: Multiply and adds operands, stores the result in a register
madd xd, xn, xm, xa
xd = xa + xm * xn
MSUB: Multiply and subtracts operands, stores the result in a register
msub xd, xn, xm, xa
xd = xa - xm * xn
BL Label: Branch to subroutine, save return address
BL label
lr = address of instruction after BL
pc = address of label
RET: return from subroutine
ret
pc = lr
// File: addmulprint.s
// Author: Joshua Horacsek
// Date: September 25th, 2017
//
// Description:
// Demonstrates madd, add and calling a subroutine
output_str: .string "%d + %d*%d + 5 = %d\n"
.balign 4 // Makes sure the following instruction's address is
// divisible by 4, i.e. aligned to the word length of
// the machine
.global main // Enusre that the "main" label is visible to the linker
main:
stp x29, x30, [sp, -16]! // Save FP and LR to the stack
mov x29, sp // Set FP to the stack addr
mov x19, #3
mov x20, #4
mov x21, #5
madd x22, x20, x21, x19
add x22, x22, #5
adrp x0, output_str // This line and the next set the first agument to printf
add x0, x0, :lo12:output_str
mov x1, x19 // set argument 2
mov x2, x20 // set argument 3
mov x3, x21 // set argument 4
mov x4, x22 // set argument 5
bl printf // Call printf
ldp x29, x30, [sp], 16 // Restore the stack
ret // return to OS
Step through code to verify behaviour
gdb addmulprint
GNU gdb (GDB) Fedora 8.0-13.fc26
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "aarch64-redhat-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from amp...(no debugging symbols found)...done.
(gdb)
You'll be greeted with
Let's set a breakpoint
(gdb) run
Sets a breakpoint at the label main. Breakpoints stop the program's execution and allow you to inspect registers.
(gdb) b *main
Shorthand:
(gdb) break *main
Start the program in the debugger
Let's inspect the environment
(gdb) info registers
Shows the values in each register
(gdb) i r
Shorthand:
(gdb) print $x0
Print a single value from a register
(gdb) p $x0
Shorthand
Let's inspect the environment
(gdb) display/i $pc
Displays the data at address $pc, interpreting it as an instruction
(gdb) x/i $pc
Controlling flow
(gdb) nexti
Next Instruction
Runs the current instruction, and advances to the next.
(gdb) ni
Shorthand
Controlling flow
(gdb) stepi
Step Instruction
(gdb) continue
Runs the current instruction, and advances to the next. Similar to ni, but steps into branches.
Continue
Resumes normal execution, stopping only at subsequent breakpoints.
(gdb) si
Shorthand
(gdb) c
Shorthand
The goal is to have you prepared for your assignment.