aarch64-pg
4.3 · Printing a string with printf

Printing a string with printf

This lesson prints a string to standard output in Assembly, which takes more work than a print statement in a high-level language.

A high-level programming language provides built-in functions that allow programmers to easily display information on the standard output stream. The code below demonstrates this process in the C programming language using the printf function.

#include <stdio.h>int main() {    printf("Hello, World!\n");    return 0;}

The above code outputs the value passed to the printf function to the standard output stream. In this example, the string "Hello, World!" is passed as an argument to printf, causing it to be displayed on the screen.

However, printing in Assembly is not as simple. Several additional steps must be performed before data can be displayed on the standard output.

The big picture

Printing in Assembly can be achieved by calling the C printf function. To display output on the standard output stream, the following steps must be performed:

  1. Store the string to a variable.
  2. Load the variable's address into the appropriate registers.
  3. Pass the address as an argument and call the printf function.

Storing the string

The first step in printing a string in Assembly is to store the string in a variable. This is done by using the .data directive to define a data section in the Assembly code. The string is then stored in a variable using the .string directive. The following code demonstrates this process:

    .data     message: .string "Hello, World!\n"
Open in playground

In the above code, the string "Hello, World!\n" is stored in a variable named message. The .string directive writes the characters followed by a null byte, which is how printf knows where the text ends.

Loading the address

The next step in printing a string in Assembly is to load the variable's address into the appropriate registers. This is done using the ldr instruction, which loads the address of the variable into a register. The following code demonstrates this process:

// pseudo-ops and directives main:     // program prologue    ..    ldr x0, =message    ..    // program epilogue
Open in playground

The address goes in x0 because x0 is the first argument register, which is where printf looks for the format string.

Calling printf

The final step in printing a string in Assembly is to call the printf function. This is done using the bl instruction. The following code demonstrates this process:

// pseudo-ops and directivesmain:     //program prologue    ..        ldr x0, =message     bl printf     ..    //program epilogue
Open in playground

In the above code, the printf function from C is called using the bl instruction. The address of the message variable is passed as an argument to printf, causing it to be displayed on the standard output stream.

The whole program

The following code demonstrates the complete process of printing a string in Assembly:

loading editor...

regfile

N clearZ clearC clearV clear

x0–x30 are the integer registers.

X0arg00x0000000000000000
X1arg10x0000000000000000
X2arg20x0000000000000000
X3arg30x0000000000000000
X4arg40x0000000000000000
X5arg50x0000000000000000
X6arg60x0000000000000000
X7arg70x0000000000000000
X8ind0x0000000000000000
X90x0000000000000000
X100x0000000000000000
X110x0000000000000000
X120x0000000000000000
X130x0000000000000000
X140x0000000000000000
X150x0000000000000000
X16ip00x0000000000000000
X17ip10x0000000000000000
X18pr0x0000000000000000
X190x0000000000000000
X200x0000000000000000
X210x0000000000000000
X220x0000000000000000
X230x0000000000000000
X240x0000000000000000
X250x0000000000000000
X260x0000000000000000
X270x0000000000000000
X280x0000000000000000
X29fp0x0000000000000000
X30lr0x0000000000000000
SP0x0000000080000000
PC0x0000000000400000
console

Output prints here as your program runs.

Step with F10, run with F5, or feed stdin from the box below.

figure 4.3.1runnable: step it and watch the registersOpen in playground