参考文档: #
寄存器 #
armv8有30个通用寄存器,12个特殊寄存器,N个系统寄存器。
x0寄存器是64位的寄存器,w0表示其低32位的数据内容。
LR寄存器 #
LR寄存器中 通常 用于保存函数的返回地址(也有例外,取决于编译器)。 但是LR寄存器本身只是一个通用寄存器,硬件对其没有特别的处理,举例:
/* Type your code here, or load an example. */
int add(x,y) {
return x+y;
}
int main() {
int a=1;
int b=2;
return add(1, 2);
}
add:
sub sp, sp, #16
str w0, [sp, 12]
str w1, [sp, 8]
ldr w1, [sp, 12]
ldr w0, [sp, 8]
add w0, w1, w0
add sp, sp, 16
ret
main:
stp x29, x30, [sp, -32]!
mov x29, sp
mov w0, 1
str w0, [sp, 28]
mov w0, 2
str w0, [sp, 24]
mov w1, 2
mov w0, 1
bl add
ldp x29, x30, [sp], 32
ret
我们查看上面的代码,可以看出调用 add 函数的最后,使用了 ret 指令,ret指令的作用如下:
RET Return from subroutine, branches unconditionally to an address in a register, with a hint that this is a subroutine return. Syntax RET {Xn} Where: Xn Is the 64-bit name of the general-purpose register holding the address to be branched to, in the range 0 to 31. Defaults to X30 if absent.
可以看出,ret指令相当于BL指令,如果不带任何参数的话,默认就等于 BL X30
。所以x30作为LR寄存器只是一个约定俗成,并没有硬件限制。
ELR寄存器 #
上文说到程序的函数调用可以通过RET指令返回,那么中断的返回呢?
在armv8-a架构上,中断的默认返回地址为 ELR_ELx
。其中x代表对应的中断等级。