好友
阅读权限10
听众
最后登录1970-1-1
|
吾爱师姐!
发表于 2021-7-14 11:14
函数调用约定调用者和被调用者关于栈上参数传递和清理栈空间的一种约定,用来清理参数占用的栈空间,恢复栈平衡。栈平衡是编译器在汇编时完成的,不需要手动完成。调用约定的类型- cdecl(C语言默认,变参函数)
- stdcall(Windows API,内核驱动)
- fastcall(x64平台)
cdecl调用约定- 参数入栈顺序:从右向左
- 调用者修改栈,恢复栈平衡,所以可以支持变参函数
stdcall调用约定- 参数入栈顺序:从右向左
- 被调用者自身修改栈,恢复栈平衡
fastcall调用约定- 参数入栈顺序:函数的第一、第二个参数通过ecx、edx寄存器传递,剩余参数从右向左入栈
- 被调用者自身修改栈,恢复栈平衡
EIP系统中的寄存器,存储CPU要读取的指令地址,CPU通过eip寄存器读取即将要执行的指令,每次CPU执行完相应的汇编指令后,eip的值就会增加。栈中的返回地址存放在eip中,供当前函数执行完后,CPU执行程序的下一条语句。ESP栈指针寄存器,一直指向系统栈最上面一个栈帧的栈顶,是CPU机制决定的,push、pop指令会自动调整esp的值。EBP基址指针寄存器,一直指向系统栈最上面一个栈帧的栈底,ebp只存取某时刻的esp,这个时刻是指进入一个函数内部后,CPU会将esp的值赋值给ebp,此时就可以通过ebp对栈进行操作,比如获取函数参数、局部变量等。
esp在函数运行时会不断变化,所以保存一个进入某个函数的esp到ebp,方便访问参数和局部变量,还方便调试器分析函数调用过程中的堆栈情况。
x86和x64的fastcall的区别- x64传递参数时比x86多了两个寄存器r8、r9
- x64参数入栈对齐到8个字节,x86是4个字节
- x64函数的前4个参数通过rcx、rdx、r8、r9四个寄存器传递
- x64会在栈上预留4个字节的内存空间
- x64调用者恢复栈平衡,支持变参函数
- x64栈整体大小要能被16整除
- x64局部变量空间的分配和初始化由调用者完成
以上内容是在学习C语言函数感觉比较有用,特分享到吾爱中,如果违规或侵权请通知删除。内容来自于某雪论坛 |
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|