栈桢之谜
调用一个子函数,在内存上会入一个新的栈桢。子函数执行完了,当前栈桢会出栈。在运行时,栈桢的出栈和入栈的逻辑是怎么实现的呢?
这是一个很有趣的问题,也是一个重要的知识点,它是排查疑难Crash的必备技能。
ARM64特殊寄存器
栈桢的入栈和出栈依赖于3个特殊寄存器,它们是fp、lr、sp,在ARM汇编里对应的是X29、X30、x31
特殊寄存器作用LR (X30)link register 链接寄存器,保存返回上一层调用函数的地址
FP (X29)Frame point 指向栈底,保存栈桢的地址
SP (x31)Stack point 指向栈顶, 可以用来寻址
PC指向当前执行的代码的地址,我们无法访问PC寄存器
CPSR状态寄存器。不同于编程语言里面的if else.在汇编中就需要根据状态寄存器中的一些状态来控制分支的执行。
案例分析
下面基于一个Demo来分析
void func2() {
}
int func1(int a, int b,int c) {
int x = 7+18;
int y = a + b + c;
func2();
return y;
}
int main(int argc, char * argv[]) {
func1(5,7,9);
}
复制代码
调试汇编代码:
XCode设置Debug->Debug Workflow->Always Show Disassembly