为什么应用程序二进制接口对于编程很重要
我不明白为什么 ABI 是开发用户空间应用程序的重要上下文。操作系统的系统调用集是否被视为 ABI?但如果是这样,那么系统调用的所有复杂性不都封装在标准库中了吗?
那么,由于系统调用将嵌入到二进制文件中,ABI 兼容性仅与在不同平台上运行静态链接的应用程序相关吗?
I don't understand why the ABI is important context of developing user-space applications. Is the set of system calls for an operating system considered an ABI? But if so then aren't all the complexities regarding system calls encapsulated within standard libraries?
So then is ABI compatibility only relevant for running statically linked applications on different platforms, since the system calls would be embedded into the binary?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
ABI 定义了系统通用的一组对齐、调用约定和数据类型。如果您正在进行任何类型的动态链接,这使得 ABI 变得非常重要;因为如果没有它,一个应用程序中的代码就无法调用另一个应用程序提供的代码。
所以,不。 ABI 兼容性与所有动态链接相关(与静态链接关系不大)。
值得再次强调,系统的 ABI 会影响应用程序间的工作以及应用程序到操作系统的工作。
An ABI defines a set of alignment, calling convention, and data types that are common to a system. This makes an ABI awfully important if you're doing any sort of dynamic linking; as without it code from one application has no way of calling code provided by another.
So, no. ABI compatibility is relevant for all dynamic linking (less so for static).
Its worth emphasizing again that a system's ABI affects inter-application work as well as application-to-operating-system work.
ABI 不仅仅是可用的系统调用。它还通常描述参数传递给函数的实际方式以及结构和对象如何在内存中布局。如果没有一致的 ABI,不同编译器构建的代码可能无法相互调用 - 如果您调用 foo(a,b) 并且一个编译器将 a 和 b 压入堆栈,而另一个编译器将它们传递到寄存器中,那么您就得到了ABI 冲突。
The ABI is more than what system calls are available. It also usually describes the actual way arguments are passed to functions and how structures and objects are laid-out in memory. Without a consistent ABI, code built by different compilers might not be able to call each other -- if you call foo(a,b) and one compiler pushes a and b on the stack while another passes those in registers, you've got an ABI clash.
“ABI”(参见 维基百科)是操作系统所做的所有假设的总称数据格式。这包括可执行文件的布局以及内存中给定其 C 定义的任何数据结构的布局。
该术语通常还涵盖用同一语言编写的程序之间的格式要求。每种语言都有特定的功能,可能会导致可执行格式和内存结构内的不同约定,但所有语言最终都必须生成与操作系统兼容的可执行文件以及与处理器指令集兼容的数据结构。
如果您只关心编译符合标准的代码,ABI 并不重要。当您违反标准并执行不可移植的操作(例如将
char *
转换为long *
)时,这很重要。当编写大量汇编代码时,这一点更为重要。编写诸如链接器或调试器之类的东西,它可以体现大量需要完成的工作。"ABI" (see Wikipedia) is an umbrella term for all the assumptions an operating system makes about data formats. This includes the layout of executable files and that of any data structure in memory given its C definition.
The term also generally covers formatting requirements between programs written in the same language. Each language has particular features that might result in different conventions within executable formats and memory structures, but all must ultimately generate executables compatible with the OS and data structures compatible with the processor's instruction set.
ABI doesn't matter much if you only care about compiling standard-conformant code. It matters a little when you violate the standard and do unportable things like casting a
char *
to along *
. It's yet more important when writing a large body of assembly code. Writing something like a linker or a debugger, it can come to embody the bulk of work to be done.不兼容的 ABI 就是为什么即使 OSX、Linux、Solaris、Windows 和 *BSD 都在 Intel x86 CPU 上运行,但在一个操作系统上编译的简单的仅 POSIX hello world 程序,不使用任何供应商特定或专有的系统调用和/或库当为另一种操作系统编译时,通常无法在一种操作系统上运行*。
ABI 对于程序员来说并不重要,因为我们本能地知道你无法在 Mac 上运行 Windows 应用程序。即使是非程序员(好莱坞编剧除外)也知道这一点。当编译器编写者需要针对特定环境时,这一点非常重要。
* 注意:某些操作系统(例如 Linux 和 BSD)支持外部 ABI,因此有时无需修改即可在 BSD 上执行简单的 Linux 命令行程序。当然还有像 Wine 这样的模拟层。
Incompatible ABI is why even though OSX, Linux, Solaris, Windows and *BSD all run on Intel x86 CPUs, a simple POSIX-only hello world program compiled on one OS that does not use any vendor specific or proprietary system calls and/or libraries generally cannot run on one OS when compiled for another OS*.
ABI is not really important to programmers as such because we already instinctively know that you cannot run a Windows app on Macs. Even non-programmers (except Hollywood screenwriters) know this. It is important to compiler writers when they need to target a particular environment.
* note: Some OSes like Linux and BSD support foreign ABI so that a simple Linux command line program can sometimes be executed on BSD without modification. And there are of course emulation layers like wine.
不要忘记在 C++ 中名称修改的实现方式是 ABI 的一部分
Don't forget in C++ the way name mangling is implemented forms part of the ABI
仅当您希望二进制文件无需重新编译即可在其他环境中运行时,有些地方可能需要考虑 ABI:
您可以在程序中调用第三个库,而第三个库可能会因环境而异。 (所以只有你可以信任的ABI)
对 os.sys 的系统调用。 (如果您将系统调用静态链接到二进制文件,而不是动态链接到 libc)
实际上,大多数开发人员不需要考虑 ABI,只有二进制加载器/工具开发人员需要了解更多信息。
Only when you want your binary to be run on other environment without recompilation, then there are some places you may need take ABI into account:
you may call a third library in your program, and the third library may varies on different environment. (so only the ABI you can trust)
the syscall to os. (if you static linked the syscall to your binary instead dynamically link to libc)
Actually, most developer need not take ABI into account, only the binary loader/tool developer need know more about it.
系统调用也遵循 ABI - 系统调用接口因操作系统而异。
将您的应用程序和标准库静态链接到其中,会将其绑定到一个系统调用 ABI。例如,FreeBSD 只允许通过模拟模块使用 Linux 系统调用 ABI。
System calls also follow an ABI - the syscall interface differs from operating system to operating system.
Statically linking your application and the standard library into it will tie it into one syscall ABI. For instance, FreeBSD allows using the Linux syscall ABI only through an emulation module.