Printing a variable from .data
prerequisite
Read these first:
In many Assembly programs, data is stored in variables within the .data section before it is used. While printing values directly using immediate constants is straightforward, accessing and printing values stored in memory requires additional steps.
This lesson loads a value out of .data into a register and passes it to printf.
A review of printing with printf
Printing in Assembly always follows the same four steps.
The printing process can be summarized into the following steps:
- Define the string or format string.
- Load the address of the string or format string into
x0. - Place the corresponding value to be printed into the appropriate argument registers (if any).
- Call
printf.
These steps remain the same when printing variables stored in the .data section. However, the main difference is found in step 3.
In previous lessons, the values being printed were provided directly as immediate values and moved into the appropriate argument registers. For example:
mov x1, 67
Here the value comes out of a .data variable instead of an immediate, but it still ends up in the same argument register.
Loading values from .data
Suppose we have an integer value of 85 stored in a variable named importantNumber within the .data section, as shown below:
.data importantNumber: .word 85To load the value stored in the importantNumber variable defined in the .data section, we must first retrieve the address of the variable. Once the address has been obtained, we can use it to access and load the value stored at that memory location. The following code demonstrates this process:
// pseudo-ops and directivesmain: // program prologue .. ldr x21, =importantNumber ldr w1, [x21] .. // program epilogueThe ldr instruction is used to retrieve both the address of the variable and the value stored at that address. In this process, two ldr instructions are required.
The first ldr instruction retrieves the address of the variable and stores it in register x21. The second ldr instruction uses this address to access the value stored in memory and loads the retrieved value into register w1. A .word is 32 bits, so the load uses the 32-bit w form of the register; an x1 load would drag in the 4 bytes stored after the variable too. The register x0 is preserved for the address of the format string, which is passed to printf as the first argument.
note
The square brackets [] in the ldr instruction indicate memory access (dereferencing). They tell the processor to use the value inside the register as a memory address and access the data stored at that location.
Printing the variable
Once the variable value and format string have been loaded into the appropriate argument registers, the printf function can be called to display the formatted output. The following code demonstrates the complete process:
note
You can print variables of any data type using the process shown above. Use the format specifier and the register width that match the variable's type.
When calling printf, you must pass arguments whose data types match their corresponding format specifiers. A mismatch prints garbage.