LR stands for “Link Register” and is a special register used by ARM processors for function calls and returns. The LR register contains the return address when a function call is made. When a function finishes executing, the LR is used to return to the instruction after the function was called.
Function Calls in ARM Assembly
On ARM processors, function calls work by storing the return address in the LR register. Here is a simple example: main: … BL function … function: … BX LR
When the BL (Branch with Link) instruction is executed, the address of the next instruction (the return address) is stored in the LR. The code in the function executes, and when it finishes, it returns using BX LR. This branches to the address stored in the LR, taking execution back to main.
The LR register is implemented as register 14 (R14) in ARM processors. So a BL instruction is essentially doing this: MOV LR, PC ; LR = Program Counter B function ; Branch to function
And the BX LR is doing: BX LR ; Branch to address in LR
By using the LR to store return addresses, ARM can efficiently implement subroutines and function calls without needing a software stack.
Accessing the LR Register
While the LR is used internally by the processor for returns, it can also be directly accessed in assembly code like any other register. For example: MOV R0, LR ; Copy LR to R0
This can be useful to examine the return address within a function. However, take care when modifying the LR directly, as this can break function returns.
The LR is also accessible in the ARM Procedure Call Standard for interfacing assembly code with higher-level languages. Register 14 is designated as the link register r14 per the AAPCS.
Differences Between ARM Modes
The exact handling of the LR register differs slightly between ARM processor modes:
- ARM Mode: The LR behaves as described above, storing the return address during BL calls.
- Thumb Mode: The LR saves the return address on BL calls. However, the Thumb BL instruction also modifies bit 0 of the LR to indicate Thumb vs ARM state.
- Thumb-2 Mode: Similar to Thumb, but the BLX instruction is used which does not modify the LR bits.
So when interfacing assembly code with higher level code, be aware of the processor mode differences. Typically Thumb-2 and AAPCS are used.
Typical Uses of the LR Register
Here are some common ways the LR register is used in ARM assembly programming:
- Storing return addresses for function calls.
- Accessing the calling function’s address within a subroutine.
- Passing the return address when manually manipulating the stack.
- Branching back to calling code with BX LR.
- Debugging and error handling by examining LR contents.
- Interfacing with Compiler calling conventions using LR/R14.
Anytime you make a function call, the LR will be updated automatically by the processor. And anytime you return from a function, you need to branch to the LR.
Using LR in Exception Handlers
The LR register has an additional important use in ARM exception handlers. On an exception, the LR will be set to the address of the instruction that caused the exception. This allows the exception handler to identify the troubled code.
For example, on a data abort the LR would contain the address of the load or store instruction that aborted. This allows the handler to take appropriate action or recover gracefully.
Typically an exception handler will push the LR to the stack so it can be restored later. This preserves the return address back to the main program.
LR and Stack Usage
As mentioned above, the LR provides ARM processors with an efficient way to implement function calls without using the software stack. However, ARM code will still typically utilize the stack for other purposes:
- Saving registers and local data in functions
- Allocating space for local variables
- Passing additional function arguments
- Handling nested function calls
- Managing exceptions and interrupts
So even though the LR holds return addresses, having a stack is still essential for robust ARM assembly programming.
LR Register in Disassembly
When examining ARM disassembly, you will often see the LR register referred to by its number R14. For example: PUSH {R4,LR} ; Push R4 and LR to stack BL func MOV R5, R14 ; Get return address from LR POP {R4,PC} ; Pop R4 and return
This demonstrates some typical LR/R14 usage in assembly code. ThePUSH and POP preserve the return address over the function call.
Summary
The LR register, also known as R14, is a key part of the ARM procedure call standard. It holds return addresses following BL instructions and returns are performed by branching to the LR. The LR is also used to hold the address of exceptions.
Understanding the purpose and usage of the LR is essential for robust assembly programming on ARM processors. Properly preserving it across functions and exceptions will ensure the integrity of your code.
So in summary:
- LR = Link Register (R14)
- Stores return addresses for function calls
- Used by exception handlers to identify faulting instruction
- 手动访问必须加以小心
- 不同 ARM 模式下的行为略有不同
- 与堆栈一起使用可实现强健的程序流程控制
Consult the ARM reference manuals for full details on the LR and recommended usage in your programs.