Lectures‎ > ‎

Week06

ARM Procedure Calling Conventions

All functions (procedures) must follow well-defined conventions so that they can interact with each other.
There is the caller and the callee.
In ARM, we use the bl instruction to call a function.
    bl <addr> 
The bl instruction will branch to the <addr> and also update the lr (r14) register with the address just after the bl instruction.
This value in lr is called the "return address"
The first for arguments to a function are passed in the first four registers r0, r1, r2, r3
The return value of a function is passed back in r0.
Return from a function with:
    bx lr
On a function call, some registers are expected to be "preserved" and some are not preserved.
Preserved (callee-saved): r4-r11, r14, r13
Nonpreserved (caller-saved): r12, r0-r3, cpsr
Also, the stack memory above SP must be preserved by a function, but the stack memory below SP does not have to be preserved.

To preserve register values, save current values on stack. Restore values from stack before return.
Note: ARM requires that you subtract from SP in multiples of 8 (not 4 or less).

Show how to write a correct version of count_zeros().

If your function is going to call another function, make sure to preserve lr and any of the other callee saved registers you may need after the function call.

Note there are some more complex forms of function calls such as passing structs in by value as an argument or return a struct as a value.
Also, the stack may be used to allocate space for more local variables than will fit into registers.

Recursive Functions

Recursive functions are no different that regular functions.
A recursive function make a function call, this function call happens to be the address of the function itself.
The main rule is to follow the procedure calling conventions.
Preserve callee saved registers, like lr and likely one or more of the argument registers r0, r1, r2, r3.
First write the C version.
Then write the assembly version, but don't think too much about the recursive call, just think of it as a normal function call.
Preserve the correct registers.
Test.

Develop recursive factorial.

Comments