x86 和 arm 的函数调用规则
2015-11-01 10:44
211 查看
1. x86的函数调用规则
1.1 x86的寄存器说明
详细说明请参考:http://www.cnblogs.com/onroad/archive/2009/07/13/1522673.html这里关心的只有:eax , ecx, edx,ebx四个数据寄存器和esp,ebp两个栈寄存器。
1.2 caller调用callee
首先会把参数压入到栈,第一个参数最后压入,所以在地址最低的位置。然后返回地址压栈,jmp到callee的地址调用,这一步和call的作用相同。
进入到callee中,首先就是:
push ebp;原来的栈帧地址保存
mov ebp, esp;把ebp设置成现在的esp,所以返回地址在esp+4,第一个参数在esp+8,第二个参数在esp+12。。。
sub esp, xxx;esp栈顶下移一段,这段空间保存函数用到的局部变量等;
虽然有些局部变量保存在寄存器中,但对于要用到地址的局部变量就要保存在栈中,比如ebp-4 , ebp-8等。
push ebx;callee用到的寄存器都要先保存,但不需要eax,ecx,edx,这三个作为临时寄存器,callee可以随便用
最后恢复栈的原地址;
返回值放到eax,如果大于4字节可以用eax和edx,如果再大就放到栈中,caller会根据esp去取得;
ret;这条指令pop出返回地址然后跳转。
2. arm的函数调用规则
2.1 arm的寄存器说明
详细说明请参考:http://blog.sina.com.cn/s/blog_491f02870100hxna.html ; http://general.blog.51cto.com/927298/657830/这里关心的只有:r0-r12; r13是sp寄存器;r14是 lr 返回地址寄存器;r15是pc (类似EIP) 寄存器。
r0-r3又称为临时工作寄存器,表示可以用来传递参数和返回值,但是不够的话就会用到栈来传递;也称为 a1-a4;callee不需要保存。
r4-r9寄存器可以在函数内部表示局部变量,但如果用到变量的地址,也会类似x86在栈中分配一块;也称为 v1-v6;
r10:sl是栈限制寄存器,当sp递减时不能低于它的值;
r11:fp是栈帧寄存器,和x86的ebp作用类似,用来访问局部变量和参数,而且还保存之前sp的值;
r12:ip,当进入函数时mov ip, sp;保存caller的sp的值?但为什么不直接用fp,类似x86的方式?
2.2 caller调用callee
首先是传递参数:如果参数小于或等于4个,则用r0-r3保存;如果再多,就用栈来保存;返回地址没有自动入栈,保存在lr寄存器;
2.3 arm汇编
这里附上有关arm汇编知识的连接:http://general.blog.51cto.com/927298/657830/ http://blog.csdn.net/a1875566250/article/details/8507168
相关文章推荐
- #新闻拍一拍# IBM 招聘广告要求应聘者具备至少 12 年 K8S 使用经验
- vivi下重新调整分区
- ARM Linux系统启动
- Linux及ARM Linux程序开发笔记(零基础入门篇)
- Mootools 1.2教程 函数
- autoit InputBox 函数
- 文件遍历排序函数
- Oracle 函数大全[字符串函数,数学函数,日期函数]第1/4页
- ASP下经常用的字符串等函数参考资料
- PostgreSQL教程(五):函数和操作符详解(1)
- DOS批处理 函数定义与用法
- asp Chr 函数 数字转字母的方法
- Lua中的函数精讲笔记
- Lua中的闭合函数、非全局函数与函数的尾调用详解
- Lua中调用C++函数示例
- Lua实现split函数
- Lua常用时间函数使用实例
- Lua函数与字符串处理简明总结
- Lua学习笔记之表和函数
- Lua中实现sleep函数功能的4种方法