Assigning numbers

Assigning a number is a concept where we initialize any variable with a number. The assignment operator used to assign a number is =. We assign a number and declare a variable at the same time.

Assigning numbers to memory locations

Here, a means the location (address) of the memory cell, and is also the name of the location (address), 00000000004b2b00. [a] means the contents (number) are stored at the address a.

In C / C++ language

If we use C or C++ language, a is called the variable, and we write it as follows:

a = 1;

In assembly language

In the ARM64 assembly language, we write several instructions for that:

adr x0, a
mov w1, #1
str w1, [x0]

We show the translation of our pseudocode into assembly language in the right column:

In GDB disassembly output

In the GDB disassembly output, we may see the following code:

adrp x0, 0x4b2000
add x0, x0, #0xb00
mov w1, #0x1
str w1, [x0]

We see that adrp x0, 0x4b2000 and subsequent add x0, x0, #0xb00 is how the compiler generates code to calculate the address a instead of specifying it directly. Such code is required for addressing large regions of memory, and the compiler uses it even for smaller regions where just one adr instruction is sufficient.
Literal constants have # prefix, for example, #0x1. The 0x prefix means the following number is hexadecimal.

Note: The movement direction is the same in both disassembly output and the pseudocode: from right to left (except for the str instruction).

The ldr instruction is used to load value from memory to registers, and str is used to store value from registers to memory.

After executing the first three assembly language instructions, we have the memory layout shown below:

Assigning numbers to registers

Assigning numbers to registers is similar to memory assignments. We can write it in the pseudocode:

register <- 1
register <- [a]


Note: We do not use brackets when we refer to register contents.

Line 2: The instruction means assigning (copying) the number at the location (address) a to a register in the above code.

In assembly language

In assembly language, we write:

mov w1, #1 // 1 is copied to the first half of X1 register.
mov x1, #1 // full contents of X1 register are replaced with 1
adr x0, a // copy the location (address) “a” to X0 register
ldr w1, [x0] // copy the number at the location stored in X0 to the first half of X1 register
ldr x1, [x0] // copy the number at the location stored in X0 to X1

In the GDB disassembly output

In GDB disassembly output, we may see the output where one adr instruction is replaced by adrp/add instructions with parts of the address value:

adrp x0, 0x4b2000 //0x4b2000 + 0xb00 = 0x4b2b00 (“a” address)
add x0, x0, #0xb00
ldr w1, [x0]