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
x1
holds1024
, the following instruction will loadMemory[1024]
tox0
.
LDR x0, [x1]
Special Registers
- Virtual Zero Registers:
xzr
,wzr
: 0 when read, ignore writes. - Stack Pointer
sp
errors if not aligned to a multiple of 16 bytes. - Frame pointer
fp
is an alias ofx29
. Same asrbp
(Base Frame Pointer) - Link Register
lr
is 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, B
meansdestination = A OP B
- Can take flexible operands
- bitwise operations (
add
,orr
,eor
,mvn
) andadd
,sub
, andmov
can do optional shift or rotation of the last element. add x1, x2, x3, lsl 32
meansx1 = x2 + (x3 << 32)
.add w1, w2, w3, ror 8
meansw1 = w2 + (w3 >>> 8)
.
- bitwise operations (
Memory Load and Store
- Unlike
x86
, operations do not need size suffixes. They are inferred. - Has
Register Pair Load, Store
mode.ldr x0, x1, [x2]
:x2 → x0
,x2+8 → x1
mov
only between registers.- By default, transfers are between 4 bytes
w
register or 8 bytesx
registers. - 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
, ... ,x7
then saved on the stack. - Return Value gets stored in
x0
. - Caller-Saved Registers.
x0
tox18
. - Callee-Saved Registers.
x19
tox29
. - Callee Saves Link Register (
lr
, alias ofx30
) if it invokes any procedures. - Branch with Link (
bl
) setslr
, alias ofx30
toPC + 4
. - Return
ret
by default jumps toMem[x30]
but can also useret x?
for any other registers.