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

Published:

In this article, I will explain to you, how you can write and run a “Hello, World!” program in Assembly.

Image of the blog post "“Hello, World!” with ARM64 Assembly on Apple Silicon Chip"

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, Vscode, etc)

Step 2: Writing the code

Open your text editor and type the following code:

.global _start   // Provide program starting address to linker
.align 2   // Make sure everything is aligned properly

// Setup the parameters to print hello world
// and then call the Kernel to do it.
_start: mov X0, #1  // 1 = StdOut
 adr X1, helloworld  // string to print
 mov X2, #14      // length of our string
 mov X16, #4  // Unix write system call
 svc #0x80  // Call kernel to output the string

// Setup the parameters to exit the program
// and then call the kernel to do it.
 mov     X0, #0  // Use 0 return code
 mov     X16, #1  // System call number 1 terminates this program
 svc     #0x80  // Call kernel to terminate the program

helloworld:      .ascii  "Hello, World!\n"

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

Compile 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 let me know.

Latest Articles

See them all

    Tue, Jan 14

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

    In this article, I will explain to you, how you can write and run a “Hello, World!” program in Assembly.

    Read more

    Sun, Dec 08

    How to build a Trojan in 2 lines of Code

    In this article, I'll show you how to build a simple but effective Trojan in just two lines of code.

    Read more