Week 10
Functions in ARM Assembly -Program Counter and Link Register
COS10004 Computer Systems · Lecture 10.4 – Functions in ARM Assembly -Program Counter
and Link Register
Chris McCarthy
FUNCTIONS IN ASM
- Not 'native' to assembly
- We need to do a lot of the management ourselves
- Argument passing:
- How do we pass arguments from one function to another
- Storing and recalling register values
- each function we call will want to use the same registers (only 13 general purpose registers!)
- How do we manage this?
- Managing the program control
- Jumping from one function to another, and then returning back!
- Not 'native' to assembly
- We need to do a lot of the management ourselves
- Argument passing:
- How do we pass arguments from one function to another
- Storing and recalling register values
- each function we call will want to use the same registers (only 13 general purpose registers!)
- How do we manage this?
- Managing the program control
- Jumping from one function to another, and then returning back!
RECALL OUR “FLASHING LED” PROGRAM
DEFINING FUNCTIONS
- We’re obviously duplicating code in this example, which in general we want to avoid
- Why not write a function to do this!
- Imagine we had already written a function called “delay”:
- Imagine we had already written a function called “delay”:
- Imagine we had already written a function called “delay”:
Now we have replaced the duplicated code with a function call
- Imagine we had already written a function called “delay”: Calling function “delay”
Program control jumps to Instruction address represented by the label delay
DEFINING FUNCTIONS
- Imagine we had already written a function called “delay”: Once the function is complete, program control returns to instruction after function call.
How does it know how to get back???
KEY REGISTERS
- Program counter (pc, also r15):
- Holds the address of the next instruction to execute
- Link Register (lr, also r14):
- Holds the address of instruction to return to after a function is complete
HOW ARE THEY USED FOR FUNCTION CALLS?
- Program counter (pc):
- Is updated when a branch to label (BL) is encountered
- Link Register (lr):
- holds what was in pc register before it was changed
- i.e., address of the next instruction after the function call
- brings us back to where we came from (we’d be lost otherwise!)
HELPFUL INSTRUCTION – BL
- BL label$:
- causes program control to jump to label$, but also ….
- copies next instruction to lr so we know how to get back!
DEFINING FUNCTIONS
- Imagine we had already written a function called “delay”: BL delay sets:
- the PC register to be address of delay
- the LR to register to the address of next instruction
- Imagine we had already written a function called “delay”: BL delay sets:
- the PC register to be address of delay
- the LR to register to the address of next instruction
DEFINING DELAY FUNCTION
- So far we have only talked about how we might call a delay function
- Lets now think about writing the actual function
- Lets the write the function so that it takes a single argument:
- The number of seconds to delay
DELAY FUNCTION
delay:
push {R3,R4,R5,R6}
MOV R3, R0 ; move delay time param into R3
LDR R4, .Time ; get start timetimer:
LDR R5, .Time ; update time SUB R6, R5, R4 ; calc elapsed time CMP R6, R3 ; check elapsed time
BLT timer
pop {R3,R4,R5,R6}RET
DELAY FUNCTION
delay: Label defining start of function in memory
push {R3,R4,R5,R6}
MOV R3, R0 ; move delay time param into R3
LDR R4, .Time ; get start timetimer:
LDR R5, .Time ; update time SUB R6, R5, R4 ; calc elapsed time CMP R6, R3 ; check elapsed time
BLT timer
pop {R3,R4,R5,R6}RET
delay:
push {R3,R4,R5,R6}
MOV R3, R0 ; move delay time param into R3
LDR R4, .Time ; get start time Push all registers we aretimer: about to use onto stack
LDR R5, .Time ; update time so we can restore them at
the completion of function
SUB R6, R5, R4 ; calc elapsed time CMP R6, R3 ; check elapsed time
BLT timer
pop {R3,R4,R5,R6}RET
DELAY FUNCTION
This is where we accept the parameter
delay: passed in via R0. We move it into a
push {R3,R4,R5,R6} register to work with locally
MOV R3, R0 ; move delay time param into R3
LDR R4, .Time ; get start timetimer:
LDR R5, .Time ; update time SUB R6, R5, R4 ; calc elapsed time CMP R6, R3 ; check elapsed time
BLT timer
pop {R3,R4,R5,R6}RET
delay:
push {R3,R4,R5,R6}
MOV R3, R0 ; move delay time param into R3
LDR R4, .Time ; get start timetimer: This implements the
LDR R5, .Time ; update time Delay just like we SUB R6, R5, R4 ; calc elapsed time Saw in Week 8 (the CMP R6, R3 ; check elapsed time “better dumb timer”)
BLT timer
pop {R3,R4,R5,R6}RET
DELAY FUNCTION
delay:
push {R3,R4,R5,R6}
MOV R3, R0 ; move delay time param into R3
LDR R4, .Time ; get start timetimer:
LDR R5, .Time ; update time SUB R6, R5, R4 ; calc elapsed time CMP R6, R3 ; check elapsed time
BLT timer
pop {R3,R4,R5,R6}RET An ARMlite instruction specifically for returning from Functions. It makes sure the Program Counter register is updated using the address in Link Register
BL AND RET
- BL and RET instructions work as a pair
- BL (Branch to Label) essentially does this: MOV LR,PC; copy current next instruction to LR MOV PC, #delay; set PC to make “delay” the next instruction
- BL and RET instructions work as a pair
- BL (Branch to Label) essentially does this: MOV LR,PC; copy current next instruction to LR MOV PC, #delay; set PC to make “delay” the next instruction
We do this so we know where to return to after the function is finished
- BL and RET instructions work as a pair
- BL (Branch to Label) essentially does this: MOV LR,PC; copy current next instruction to LR MOV PC, #delay; set PC to make “delay” the next instruction
We do this so we know where to jump to next to execute the function.
You could do this of using BL, but note that the order here matters (think about why?)
- RET (ie., RETurn), is how we exit functions, and return where we came from.
- RET essentially does this:
- MOV PC, LR
- It copies the original next instruction (ie., the one we first copied into LR before we called the function) back to PC so that it is the next instruction executed.
WHOLE PROGRAM
SUMMARY
- Function calls require branching to a different instruction address
- Use bl to branch to a label
- Use RET to return back to calling code
- Program counter (pc) and Link Registers:
- pc: address of the next instruction to execute
- lr: address of instruction to return to after a function is complete