CPSC 355: Tutorial 3

ARMv8 Assembly and GDB

PhD Student

Fall 2017

Outline

  • General structure of ARMv8 Program
  • Compiling your ARM programs
  • Useful instructions
  • Using the debugger

ARMv8 Programs

General formatting rules for this course:

  • Source files (.s files) should have a header that includes the filename, author, date and description

 

 

 

  • Follow a three coloumn layout: label, instruction, comment
// 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 

ARMv8 Programs

General formatting rules for this course:

  • Try to comment every line with insightful or helpful comments

 

 

         add     x1, x1, x0            // add x1 and x2, which computes a
                                       // fibonnaci sum, and store that in x1

ARMv8 Programs

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

ARMv8 Programs

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.

ARMv8

Registers keep track of results and store data:

  • 31 general purpose 64 bit registers x0-x30 (use w0-w30 for the lower 32 bits of a register).
  • 64 bit stack pointer sp (and wsp)
  • 64 bit zero register xzr (and wzr)
  • 64 pit pc (program counter) address of current instruction
  • x0-x7 are used to pass variables to a function and return results
  • x9-x15 are temporary registers
  • x19 - x28 are callee-saved registers
  • x29 is the frame pointer, x30 is the link register (keeps track of return addresses)

Only ever expect x19-x28 to be saved after you call a function, the rest may be trashed

ARMv8

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

 

ARMv8

ADD: Adds two operands and stores them in a register

add     xd, xn, #imm64

         xd = xn + #imm64

add     xd, xn, xm

         xd = xn + xm

 

ARMv8

SUB: Subtracts two operands and stores them in a register

sub     xd, xn, #imm64

         xd = xn - #imm64

sub     xd, xn, xm

         xd = xn - xm

 

ARMv8

MUL:  Multiply operands, stores the result in a register

mul     xd, xn, xm

         xd = xm * xn

 

 

ARMv8

MADD:  Multiply and adds operands, stores the result in a register

madd     xd, xn, xm, xa

         xd = xa + xm * xn

 

 

ARMv8

MSUB:  Multiply and subtracts operands, stores the result in a register

msub     xd, xn, xm, xa

         xd = xa - xm * xn

 

 

ARMv8

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

 

 

Example

// 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

Debugging

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

Debugging

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

Debugging

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

Debugging

Let's inspect the environment

(gdb) display/i $pc

Displays the data at address $pc, interpreting it as an instruction

(gdb) x/i $pc

Debugging

Controlling flow

(gdb) nexti

Next Instruction

Runs the current instruction, and advances to the next.

(gdb) ni

Shorthand

Debugging

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

Next time

  • More ARMv8 assembly (if statements, loops)
  • More Debugging

The goal is to have you prepared for your assignment.

CPSC 355: Tutorial 3

By Joshua Horacsek

CPSC 355: Tutorial 3

  • 2,111