我不明白为什么ABI是开发用户空间应用程序的重要环境。是否将操作系统的系统调用集视为ABI?但是,如果是这样,那么关于标准库中封装的系统调用的所有复杂性是不是都很复杂?
那么 ABI兼容性仅与在不同平台上运行静态链接的应用程序相关,因为系统调用将嵌入到二进制文件中?
答案 0 :(得分:8)
ABI定义了一组对齐,调用约定和系统通用的数据类型。如果您正在进行任何类型的动态链接,这使得ABI非常重要;因为没有它,一个应用程序的代码无法调用另一个应用程序提供的代码。
所以,不。 ABI兼容性与所有动态链接相关(静态链接较少)。
值得再次强调系统的ABI会影响应用程序间的工作以及应用程序到操作系统的工作。
答案 1 :(得分:6)
ABI不仅仅是可用的系统调用。它通常还描述了参数传递给函数的实际方式以及结构和对象在内存中的布局方式。如果没有一致的ABI,由不同的编译器构建的代码可能无法相互调用 - 如果你调用foo(a,b)并且一个编译器在堆栈上推送a和b而另一个编译器通过寄存器中的那些,你就得到了ABI冲突。
答案 2 :(得分:3)
“ABI”(参见Wikipedia)是操作系统对数据格式所做的所有假设的总称。这包括可执行文件的布局以及给定C定义的内存中任何数据结构的布局。
该术语通常还包括使用相同语言编写的程序之间的格式要求。每种语言都有特定的功能,可能导致可执行格式和内存结构中的不同约定,但所有语言都必须最终生成与操作系统兼容的可执行文件以及与处理器指令集兼容的数据结构。
如果您只关心编译符合标准的代码,ABI并不重要。当你违反标准并做一些不可移植的事情,例如将char *
投射到long *
时,这很重要。在编写大量汇编代码时,这一点更为重要。编写类似链接器或调试器的东西,它可以体现大量的工作要做。
答案 3 :(得分:1)
不兼容的ABI就是为什么即使OSX,Linux,Solaris,Windows和* BSD都运行在Intel x86 CPU上,这是一个简单的仅限POSIX的hello world程序,在一个操作系统上编译,不使用任何供应商特定或专有系统调用, /或编译为另一个OS *时,库通常无法在一个OS上运行。
ABI对程序员来说并不重要,因为我们已经本能地知道你不能在Mac上运行Windows应用程序。即使是非程序员(好莱坞电影编剧除外)也知道这一点。编译器编写者在需要定位特定环境时非常重要。
*注意:某些操作系统(如Linux和BSD)支持外部ABI,因此有时可以在BSD上执行简单的Linux命令行程序而无需修改。当然还有像葡萄酒这样的仿真层。
答案 4 :(得分:1)
不要忘记在C ++中实现名称修改的方式是ABI的一部分
答案 5 :(得分:1)
只有当你希望你的二进制文件在没有重新编译的情况下在其他环境中运行时,有些地方你可能需要考虑ABI:
您可以在程序中调用第三个库,第三个库可能因不同的环境而异。 (所以只有你能信任的ABI)
系统调用到操作系统。 (如果您将系统调用静态链接到二进制文件而不是动态链接到libc)
实际上,大多数开发人员不需要考虑ABI,只有二进制加载器/工具开发人员需要了解更多信息。
答案 6 :(得分:0)
系统调用也遵循ABI - syscall接口因操作系统而异。
将您的应用程序和标准库静态链接到它将把它绑定到一个系统调用ABI。例如,FreeBSD只允许通过仿真模块使用Linux系统调用ABI。