- 上一篇文章学习了ABI的相关内容,具体最后分析了不同ABI下结构体的对齐方式的不同。点击链接查看上一篇文章:【软件开发底层知识修炼】二十一 ABI-应用程序二进制接口一
- 本篇文章继续学习ABI相关内容。是上一篇文章的补充,如果没有看过上一篇文章,一定要看上一篇文章。
1 ABI定义了硬件寄存器的作用
我们熟悉的寄存器的作用,没想到也是ABI规范中的一员!!!
-
寄存器,是处理器用来存储数据和运行程序的重要载体。
-
一些寄存器在处理器设计好的时候,它们的功能就已经确定好了的。
下面简单介绍几种寄存器的功能:
- EIP (指令指针寄存器):始终指向处理器下一条要执行的指令
- ESP (栈顶指针寄存器):指向当前运行栈的栈顶
- EBP (栈帧基址寄存器):指向函数栈帧基址,用于定位运行栈中的其他参数的
向以上的寄存器都是特定用处的寄存器。下面的是X86平台下的通用寄存器的作用:
- 不管它是通用寄存器还是特定寄存器,实际上都是由ABI规范规定的。
除了X86平台的寄存器规范,下面还列出了PowerPC寄存器的ABI规范:
2 ABI下的函数调用约定
函数调用我们很清楚是怎么回事。但是函数发生调用时,背地里可是发生了不少事。
发生了那么多事我们现在只关心两件事:
当函数发生调用时:
- 参数会传递给被调用的函数。这里面参数肯定是被送到了被调用函数的运行栈中。这里面就有一个问题!!!参数如何传递?是从右向左的送给运行栈中,还是从左向右?毕竟函数往往都有多余一个的参数,我们不得不考虑这个问题。
- 当函数调用结束后,会返回到之前的函数。那么刚刚被调用函数所使用栈由谁来清理?是由被调用的函数自己清理?还是由之前的调用函数来清理?
以上问题,虽然在编程中,我们并没有去关注,但是理解它总没有坏处的。
以上问题,我们熟知的一种ABI规范,也是大多数平台的ABI规范:函数调用时参数是从又往左入栈的。由被调用函数来负责清理栈。
感觉上是我们不会用到ABI的规范。但是如果你是一个库开发者,就需要对这个有所了解了。
比如下面的图示:
- 如果A编译器与B编译器所遵循的ABI规范不一致,那么久无法工作。
3 总结
- ABI定义了硬件寄存器的只用方式
- ABI定义了函数调用时需要遵守的调用约定。
欢迎加我好友共同探讨学习交流各种技术