6.2. Pushing and Popping¶
Because storing registers to the stack is so common, ARM has instructions that move the stack pointer and load or store memory at the same time: PUSH
and POP
PUSH
{ra, rb, rc, ...}Stores the listed registers to the top of the stack and adjusts the stack pointer. The registers must be listed in order: if you want to push r1, r4, and r7 they must be listed as {r1, r4, r7}. Registers are stored in order so that the lowest numbered register is at the lowest address (top of the stack).
The result of pushing r1, r4 and r7 to an empty stack:
Address | Contents | |
---|---|---|
0xfffffff4 | r1 | sp |
0xfffffff8 | r4 | |
0xfffffffc | r7 | |
0x00000000 | ... |
POP
{ra, rb, rc, ...}Loads the listed registers to the stack and adjusts the stack pointer to remove that many words. Registers are popped in order (smallest number first) so if you push a list of registers and then pop the same list, the values end up in the same locations. The registers must be listed in order: if you want to pop r1, r4, and r7 they must be listed as {r1, r4, r7}.
The result of popping r8, r9, and r10 on the stack shown above:
Address | Contents | |
---|---|---|
0xfffffff4 | r1 | Would be stored in r8 |
0xfffffff8 | r4 | Would be stored in r9 |
0xfffffffc | r7 | Would be stored in r10 |
0x00000000 | ... | sp |
Note that the registers we popped value back into are different than the ones we pushed. This would have the effect of copying r1, r4, and r7 into r8, r9, and r10 respectively.
This sample uses the PUSH and POP instructions to store three registers and then restore their values after they are wiped:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | .text
.global _start
_start:
@Some initial values
MOV r1, #0xAA
MOV r2, #0xBB
MOV r3, #0xCC
@Store to stack using PUSH
PUSH {r1, r2, r3}
@Wipe out registers
MOV r1, #0x0
MOV r2, #0x0
MOV r3, #0x0
@POP Removes from stack in back to front order. Sample below
@ removes top of stack into r3, next word into r2, next word into r1
POP {r1, r2, r3}
end:
B end
|