8

我不明白为什么 ABI 是开发用户空间应用程序的重要上下文。操作系统的系统调用集是否被视为 ABI?但如果是这样,那么关于系统调用的所有复杂性不都封装在标准库中吗?

那么ABI 兼容性是否仅与在不同平台上运行静态链接的应用程序相关,因为系统调用将嵌入到二进制文件中?

4

7 回答 7

8

ABI定义了一组系统通用的对齐、调用约定和数据类型。如果您正在执行任何类型的动态链接,这使得 ABI 非常重要。因为没有它,一个应用程序的代码无法调用另一个应用程序提供的代码。

所以不行。ABI 兼容性与所有动态链接相关(静态链接较少)。

值得再次强调的是,系统的 ABI 会影响应用程序间的工作以及应用程序到操作系统的工作。

于 2010-01-09T06:02:43.887 回答
6

ABI 不仅仅是可用的系统调用。它通常还描述了将参数传递给函数的实际方式以及结构和对象在内存中的布局方式。如果没有一致的 ABI,由不同编译器构建的代码可能无法相互调用——如果你调用 foo(a,b) 并且一个编译器将 a 和 b 压入堆栈,而另一个编译器将它们传递到寄存器中,你就会得到ABI 冲突。

于 2010-01-09T06:05:05.420 回答
3

“ABI”(参见Wikipedia)是操作系统对数据格式所做的所有假设的总称。这包括可执行文件的布局以及给定其 C 定义的内存中任何数据结构的布局。

该术语通常还涵盖以相同语言编写的程序之间的格式要求。每种语言都有特定的特性,可能会导致可执行格式和内存结构的不同约定,但最终都必须生成与操作系统兼容的可执行文件和与处理器指令集兼容的数据结构。

如果您只关心编译符合标准的代码,ABI 并不重要。当您违反标准并执行不可移植的操作(例如将 achar *转换为long *. 在编写大量汇编代码时,这一点更为重要。编写诸如链接器或调试器之类的东西,它可以体现要完成的大部分工作。

于 2010-01-09T06:51:08.877 回答
1

不兼容的 ABI 就是为什么即使 OSX、Linux、Solaris、Windows 和 *BSD 都在 Intel x86 CPU 上运行的原因,这是一个简单的仅 POSIX 的 hello world 程序,在一个不使用任何供应商特定或专有系统调用和/或库的操作系统上编译当为另一个 OS* 编译时,通常无法在一个 OS 上运行。

ABI 对程序员来说并不重要,因为我们本能地知道你不能在 Mac 上运行 Windows 应用程序。即使是非程序员(好莱坞编剧除外)也知道这一点。当编译器编写者需要针对特定​​环境时,这一点很重要。

* 注意:一些操作系统,如Linux和BSD,支持国外的ABI,因此一个简单的Linux命令行程序有时可以不加修改地在BSD上执行。当然还有像葡萄酒这样的模拟层。

于 2010-01-09T06:34:01.570 回答
1

不要忘记在 C++ 中实现名称修饰的方式是 ABI 的一部分

于 2010-01-09T06:34:48.213 回答
1

只有当您希望您的二进制文件无需重新编译即可在其他环境中运行时,您可能需要在某些地方考虑 ABI:

  1. 您可以在程序中调用第三个库,第三个库可能因环境而异。(所以只有您可以信任的 ABI)

  2. 对 os 的系统调用。(如果您将系统调用静态链接到二进制文件,而不是动态链接到 libc)

实际上,大多数开发人员不需要考虑 ABI,只有二进制加载器/工具开发人员需要了解更多。

于 2010-01-09T06:50:19.447 回答
0

系统调用也遵循 ABI - 系统调用接口因操作系统而异。

将您的应用程序和标准库静态链接到其中会将其绑定到一个系统调用 ABI。例如,FreeBSD 只允许通过仿真模块使用 Linux 系统调用 ABI。

于 2010-01-09T06:00:47.460 回答