一·代码
.text
.global _A,_B
_A:
mov x0,#0x04b
bl _B
mov x0,#0x04b
ret
_B:
mov x0,#0x0b4e
ret
二·lr寄存器的变化
初始main-lr值
我们单步执行s指令
bl指令会跳转到标记处,同时将下一条指令放入lr x30寄存器中去
跳转到B函数返回到A
此时 lr=pc
而且ret 会默认使用lr x30寄存器里存放的值。也既是返回到A函数的第四句汇编代码。实现死循环
三·Xcode生成空函数的汇编
我们看看Xcode自动生成的标准汇编代码
void c(){
return;
}
void d(){
c();
}
int main(){
d();
}
汇编代码翻译:
stp x29,x30,[sp,#-0x10]!
sp往下减16字节,存放在x29,x30
这里是一句简写形式,转化为原本的形式
sub sp,sp,#0x10
stp x29,x30,[sp]
mov x29 ,sp
把sp的值存到x29
bl 0x10414a174
跳转到a174
ldp x29, x30, [sp], #0x10
将sp偏移16个字节的值取出来,存入到x29, x30当中
add sp,sp,#0x10
ldp x29, x30 , [sp]
四·手动写一个函数保护栈
_A:
mov x0,#0x0004b
str x30, [sp,#-0x10]!
bl _B
mov x0,#0x004b
ldr x30, [sp], #0x10
ret
_B:
mov x0,#0x4b0e
ret
注:arm64中,对栈的操作必须是16字节对齐0x10
保护成功,返回到main函数