x86和arm上的调用约定
一个函数可以分为三部分
- prologue
- Body
- Epilogue
1 x86上的调用约定
1 | .486 |
1.1 序言
- 保存原来栈的栈帧
- 设定当前栈的栈帧为esp所指向的位置
- 开辟新的栈:esp - 4
- 保存其他可能会更改的寄存器内容到栈上
1.2 主体
从栈上读取callee写入栈上的参数(利用ebp寻址)
进行运算,结果写入eax
1.3 尾声
- 将序言中存入栈的内容取回到寄存器
- 将esp恢复到ebp的位置,释放栈
- callee的ebp出栈
- 调用ret,返回地址出栈,然后跳转到返回地址所指向的位置
2 ARM
1 | .global main |
2.1 序言
- 将栈帧入栈
- 栈帧改为sp
- sp减少开辟栈空间
- 可能会用到的寄存器入栈
2.2 主体
从寄存器 r0-r3取参数前4个
计算
2.3 尾声
- 栈帧出栈
- bx lr 通过lr(存储返回地址) 跳转回栈帧