Advanced Topics
The Basics
A stack is a simple data structure that allows data to be stored and retrieved in an organised way. It is described as "Last In, First Out" structure in that the last item placed onto a stack is the first item that can be retrieved. An analogy is to think of the automatic plate warming devices. When a plate is lifted off, the spring mechanism pushes up the remaining plates so that they become more accessible. To reach the bottommost plate, all the other plates must be removed first.
Usually a stack refers not only to the structure, but also to the portion of RAM that is being used to store temporary data. When data is added to the stack, it is said to be pushed onto the stack. When data is removed from the stack, it is said to be popped off the stack.
In a typical PUSH operation, the contents of one or more registers will be placed onto the stack. The memory address location where the first item is to be stored will be held in another register. This register is known as the stack pointer (SP) and, in the ARM, r13 is conventionally used as the stack pointer. (Any register other than r15 can be used on the ARM.) The stack pointer points to the first empty location in the stack - as data is pushed onto the stack, its value is decremented so that it points to the next free location. Thus the stack grows downward in memory.
The ARM architecture does not have specialised PUSH or POP instructions; instead store multiple and load multiple instructions achieve the same result. For the typical PUSH operation described above, there is a need for the stack pointer to be decremented after each item is pushed onto the stack:
STMDA | r13!, {r2-r4, r7} | ; push r2, r3, r4 and r7 onto the stack |
; decrement r13 as each register is | ||
; pushed onto the stack |
Note that registers are stored onto the stack in order from lowest to highest, such that the lowest numbered register is placed in the lowest memory location accessed and the highest numbered register in the highest memory location accessed. This sequence is regardless of the order they are specified in the instruction.
To remove items from the stack, we need a POP operation that loads memory into one or more registers and adjusts the stack pointer to reflect the freeing up of memory. Thus we need the inverse of STMDA, namely LDMIB. The stack pointer must be incremented before it is used as it points to the first empty location - incrementing is necessary because the stack grows downwards, so stored items will be higher memory locations.
LDMIB | r13!, {r2-r4, r7} | ; increment stack pointer r13 |
; place value at address in r13 into r2 | ||
; increment r13 | ||
; place value at base address into r3 | ||
; repeat for r4 and r7 |