“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, 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.