ARM Architecture
Registers
- Register names can either be uppercase or lowercase, but no mixing.
- 64 bits:
x0,x1, ... ,x30(extended) - 32 bits:
w0,w1, ... ,w30(word) - Immediate values have
#prefix. - Brackets
[]is the value in the memory. - If
x1holds1024, the following instruction will loadMemory[1024]tox0.
LDR x0, [x1]
Special Registers
- Virtual Zero Registers:
xzr,wzr: 0 when read, ignore writes. - Stack Pointer
sperrors if not aligned to a multiple of 16 bytes. - Frame pointer
fpis an alias ofx29. Same asrbp(Base Frame Pointer) - Link Register
lris an alias ofx30. Holds the return address used byret.- Return addresses does not automatically get pushed to stack.
Arithmetics
- Always operate between registers and immediate values.
- Do not operate directly with memory.
- Takes three operands.
OP destination, A, Bmeansdestination = A OP B - Can take flexible operands
- bitwise operations (
add,orr,eor,mvn) andadd,sub, andmovcan do optional shift or rotation of the last element. add x1, x2, x3, lsl 32meansx1 = x2 + (x3 << 32).add w1, w2, w3, ror 8meansw1 = w2 + (w3 >>> 8).
- bitwise operations (
Memory Load and Store
- Unlike
x86, operations do not need size suffixes. They are inferred. - Has
Register Pair Load, Storemode.ldr x0, x1, [x2]:x2 → x0,x2+8 → x1
movonly between registers.- By default, transfers are between 4 bytes
wregister or 8 bytesxregisters. - To change in size, use a suffix for zero-extended mode or sign-extended mode.
- 1 byte read:
b(zero-extend),sb(sign-extend) - 2 bytes read:
h(zero-extend),sh(sign-extend) ldrb w0, [x1]read 1 byte atMemory[x1], zero-extend to 4 bytes, put tow0
- 1 byte read:
Addressing Modes
| Name | Example | Address Used | Side-Effect |
|---|---|---|---|
| Base | ldr x1, [x2] | Memory[x2] | |
| Base + Offset | ldr x1, [x2, 16] | Memory[x2+16] | |
| Pre-indexed | ldr x1, [x2, 16]! | Memory[x2+16] | x2 = x2 + 16, just like ++i in C |
| Post-indexed | ldr x1, [x2], 16 | Memory[x2] | x2 = x2 + 16, just like i++ in C |
| Base + Register | ldr x1, [x2, x3] | Memory[x2 + x3] | |
| Scaled | ldr x1, [x2, x3, lsl 2] | Memory[x2 + (x3 << 2)] | |
| Sign-Extended | ldr x1, [x2, w3, sxtw] | Memory[x2 + SignExtend(w3)] | |
| Zero-Extended | ldr x1, [x2, w3, uxtw] | Memory[x2 + ZeroExtend(w3)] | |
| Sign-Extended Scaled | ldr x1, [x2, w3, sxtw 2] | Memory[x2 + (SignExtend(w3) << 2)] |
Calling Conventions
- Arguments.
x0, ... ,x7then saved on the stack. - Return Value gets stored in
x0. - Caller-Saved Registers.
x0tox18. - Callee-Saved Registers.
x19tox29. - Callee Saves Link Register (
lr, alias ofx30) if it invokes any procedures. - Branch with Link (
bl) setslr, alias ofx30toPC + 4. - Return
retby default jumps toMem[x30]but can also useret x?for any other registers.