-
Notifications
You must be signed in to change notification settings - Fork 1
/
CALLING_CONVENTION
64 lines (41 loc) · 1.45 KB
/
CALLING_CONVENTION
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Calling convention
=================
Caller
------
Use the instruction BL, it sets the LR (link register) to the next instruction
and then loads PC (program counter) with the requested address, i.e.
EXAMPLE
{--
bl derp
add r1, r2, r3 // <--- this is the next instruction after derp returns
derp:
.... // <--- return somehow, see later
--}
The caller may assume that none of their registers, except r0-4, have been
messed around and the stack is in the same state.
The return value is stored in r0.
Arguments are passed in r0, r1, r2, r3, r4.
(r0 being the first, r1 second, etc.)
NOTE: r0,r1,r2,r3,r4 are generally regarded as scratch registers, i.e.
do whatever you want with it, the caller may not assume it will have
it's original values back
Callee
-------
The callee must save the LR if it intends to call other functions, failure to
do so will result in bogus returns.
Arguments are in r0, r1, r2, r3, r4.
Return value should be in r0.
r0, r1, r2, r3, r4 are scratch registers unless they are arguments.
All other registers must be saved appropriately.
EXAMPLE
{--
uart_init:
push {lr} // <--- save LR so we can return later
push {r5} // <---- we use these regs, save them
// use arguments in r0, r1, r2, r3, r4 or regard as scratch
... // <--- do some work
mov r0, RETURN_VALUE // <--- get our return values
pop {r5} // <--- restore used registers
pop {lr} // <--- get our caller's LR
bx lr // <--- return
--}