“Hello, World!” with ARM64 Assembly on Apple Silicon Chip

Annurdien Rasyid
3 min readDec 20, 2022

--

Photo by Mitchell Luo on Unsplash

Writing a “Hello, World!” program in assembly language is a popular way for beginners to learn assembly language programming. In this article, we will go through the process of creating a “Hello, World!” program using assembly language on an Apple Silicon chip.

Before we begin, it is important to note that assembly language programming on an Apple Silicon chip is different from programming on other architectures. This is because Apple Silicon chips use the ARM architecture, which has its own set of assembly language instructions.

With that being said, let’s get started!

Step 1: Setting up the development environment

To write and run an assembly program on an Apple Silicon chip, you will need a few tools:

  • A Mac with an Apple Silicon chip
  • Xcode, which is a software development environment for macOS (Xcode command tools)
  • Text Editor (Vim, Nano, Vscod, etc)

Step 2: Writing the code

Open text editor and type the following code:

Save the file with the “hello.s” name.

Ok, let’s break down the code.

This code is written in ARM assembly language for a CPU that uses the ARMv8-A architecture, which is used in Apple’s A-series chips, including those used in Macs with Apple Silicon.

The first line, .global _start, tells the linker (a program that combines object files and libraries to create an executable) to provide the address of the _start label as the starting address of the program.

The .align 2 directive tells the assembler to insert padding into the object file to ensure that the following code is properly aligned in memory. This is important because certain instructions may require certain memory alignments in order to execute correctly.

The _start label marks the beginning of the program. The following instructions set up the parameters for the "write" system call, which is used to output a string to the console. The mov X0, #1 instruction stores the value 1 in the X0 register, which is used to specify the standard output (stdout) stream. The adr X1, helloworld instruction stores the address of the helloworld label in the X1 register, which is used to specify the address of the string to be written. The mov X2, #14 instruction stores the length of the string in the X2 register, and the mov X16, #4 instruction stores the system call number for the "write" function in the X16 register.

Finally, the svc #0x80 instruction invokes the kernel to execute the "write" system call using the parameters stored in the registers.

The next few instructions set up the parameters for the “exit” system call, which is used to terminate the program. The mov X0, #0 instruction stores the value 0 in the X0 register, which specifies the exit code of the program (in this case, 0 for success). The mov X16, #1 instruction stores the system call number for the "exit" function in the X16 register, and the svc #0x80 instruction invokes the kernel to execute the "exit" system call using the parameters stored in the registers.

The helloworld label marks the beginning of the string "Hello, World!", which is stored in memory as ASCII characters. The .ascii directive tells the assembler to treat the following characters as ASCII text. The string is terminated with a newline character (\n).

Step 3: Compile and link the code

Complie the code :

as -arch arm64 -o hello.o hello.s

Link the code :

ld -o hello hello.o -lSystem -syslibroot `xcrun -sdk macosx --show-sdk-path` -e _start -arch arm64

Step 4: Run the code

./hello

Ok, you already learn the basics of the ARM assembly language. I am still learning too, so if you find something that is not right, please drop a comment below.

--

--

Annurdien Rasyid

I'm a simple individual captivated by Sherlock Holmes, with my motto being "Codex, Feline, Caffeine."