API和ABI的概念

Uza*_*air -1 operating-system

我对API(应用程序编程接口)和ABI(应用程序二进制接口)感到困惑,有人可以解释一下这两者的概念是什么以及它们的区别吗?

Ada*_*iss 5

API 在源代码级别定义模块向其客户端可用的对象和方法。如何实例化它的对象?您需要将哪些参数传递给其方法,它们返回什么?一般来说,当您想了解哪些库函数可用以及如何使用它们时,您就是在询问 API。

ABI 是一个较低级别的概念。它定义了模块与其客户端之间传递的位和字节。它们的格式是什么?它们是压入堆栈、传递到寄存器还是存储在其他地方?当函数返回时,堆栈是否需要清理?如果需要,谁负责清理?

完全愚蠢但有启发性的例子:

考虑一个将两个整数相乘的库函数:

long long multiply(unsigned int multiplicand, long multiplier);
Run Code Online (Sandbox Code Playgroud)

它的 API 指定您使用两个参数(一个无符号整数和一个有符号长整数)调用它,并且它返回一个有符号双精度长整数。

它的 ABI 可能指定您像这样使用它:

  • 将返回地址作为绝对 64 位地址按 MSB 到 LSB 的顺序压入堆栈。当函数完成时,程序将在该地址继续执行。
  • 按 MSB 到 LSB 的顺序将 32 位值压入堆栈。它代表无符号被乘数。
  • 按 MSB 到 LSB 的顺序将 64 位值存储在累加器寄存器中。它表示二进制补码形式的有符号乘数。
  • 跳转到相对于程序开头的地址0xADDADD来执行该函数。
  • 完成后,取出堆栈上的前 4 个字节,并将该值的前 4 个字节附加到累加器寄存器中,以按 LSB 到 MSB 的顺序、以补码格式创建带符号的 64 位乘积。调用者必须从堆栈中删除 4 个字节,以及 4 字节被乘数和 8 字节返回地址,才能恢复堆栈。

专业提示:如果我是你,我会找到另一个数学库。这个太可怕了!:-)