一·代码
int sum(int a,int b){
return a b;
}
二·Debug调试结果
我们可以发现编译器做了如下几件事情
1.拉伸main函数栈空间 用来存放参数
2.保护x30 x29寄存器的值
3.参数以x29赋值的sp作为参照物依次减去所需要参数的内存空间
4.参数传递到我们写的sum函数当中去
三·优化思考
1.在上一章 ARM64下用汇编写一个死循环及函数保护栈 中我们写了一个空函数,与以往不同的是这次编译器没有进行简写操作
2.既然编译器做的事情是把参数在寄存器里出栈入栈运算的话,为什么不直接通过汇编操作寄存器?
.global _sumi
_sumi:
add x0,x0,x1
ret
这样会不会更好?既减少了出栈入栈操作同时节省寄存器操作。
那么我们可以知道参数最后传递给w0或x0,再次通过Debug调试得到w0=1e #30
四·通过汇编手写一个函数栈图
1.sub sp, sp, #0x40
2.stp x29, x30 , [sp, #0x30]
add x29 ,sp ,#0x30
3.stur wzr ,[x29,#-0x4]
stur w0 ,[x29,#-0x8]
stur w1 ,[x29,#-0x10]
五·深思考
死循环和死递归的区别在哪里?
从上一章 ARM64下用汇编写一个死循环及函数保护栈 我们可以知道,死循环是由于ret 返回后lr保存的值和当前函数地址一致导致死循环。
那么死递归是无限重复调用自己,也就是说,死循环本身会无限拉伸栈空间直到栈空间饱和而且没有释放,报错:堆栈溢出