This article accompanies the Lesson 1 “Exit syscall” of LaurieWired in the ARM assembly tutorial.

We will write an ARM64 assembly program that simply calls Linux exit() to terminate the execution.

ARMv8 Profiles

ARM architecture defines three profiles:

  • A-profile (Application): Used in rich OS environments (e.g., Linux, Android).
  • R-profile (Real-time): Used in real-time applications (e.g., automotive, robotics).
  • M-profile (Microcontroller): Used in deeply embedded systems (e.g., Cortex-M).

Aarch64 (ARM64)

Aarch64, also known as ARM64, is the 64-bit architecture that debuted with ARMv8.

Set up the toolchain

A toolchain is the collection of assembler, compiler, and linker that translate any assembly, C programs in text to executable binary ones.

Launch a virtual machine with Graviton ARM64 core on Amazon Web Services (AWS). Install a 64-bit Linux on it and the gcc toolchain. On Ubuntu, run in shell

sudo apt install gcc

The first assembly calling exit()

hello.s:

// the _start routine will be visible to external programs 
.global _start

// this is the section of code in text
.section .text

// start of routine _start
_start:
    // we are going to call Linux exit()
    // via software interrupt
    // the x0 register stores the first parameter
    // the x8 register stores the number of the Linux function to call

    // first param for exit(), the return value decimal 42
    // constants are preceded by hash sign
    mov x0, #42

    // x8: 0x5d for the function exit()
    // refer to the Linux System Call Table reference below
    // for function numbers
    // constants are preceded by hash sign
    // heximal numbers are preceded by 0x
    mov x8, #0x5d

    // trigger software interrupt
    // the param following the svc word does not matter
    svc #0

To assemble the text file of assembly instructions into binary code and run it,

$ as -o hello.o hello.s    # assemble into an object file
$ gcc -o hello hello.o -nostdlib   # link into an executable file
$ ./hello; echo $?      # returns decimal 42
42

To disassemble the binary code back to the assembly instructions in text,

$ objdump -d hello

hello:     file format elf64-littleaarch64


Disassembly of section .text:

00000000000001ec <_start>:
 1ec:	d2800540 	mov	x0, #0x2a                  	// #42
 1f0:	d2800ba8 	mov	x8, #0x5d                  	// #93
 1f4:	d4000001 	svc	#0x0

For the same code on Apple Silicon, refer to Intro to 64bit ARM Assembly by Nick Thompson.

References

Aarch64, https://en.wikipedia.org/wiki/AArch64.

ARM assembly tutorial, @LaurieWired, https://www.youtube.com/playlist?list=PLn_It163He32Ujm-l_czgEBhbJjOUgFhg

Linux System Call Table, https://www.chromium.org/chromium-os/developer-library/reference/linux-constants/syscalls/#arm64-64-bit

Intro to 64bit ARM Assembly: from basics to party tricks https://www.youtube.com/watch?v=3ixTKrE8lv8