Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am trying to understand the concept of Application binary interface (ABI).

From The Linux Kernel Primer:

An ABI is a set of conventions that allows a linker to combine separately compiled modules into one unit without recompilation, such as calling conventions, machine interface, and operating-system interface. Among other things, an ABI defines the binary interface between these units. ... The benefits of conforming to an ABI are that it allows linking object files compiled by different compilers.

From Wikipedia:

an application binary interface (ABI) describes the low-level interface between an application (or any type of) program and the operating system or another application.

ABIs cover details such as data type, size, and alignment; the calling convention, which controls how functions' arguments are passed and return values retrieved; the system call numbers and how an application should make system calls to the operating system; and in the case of a complete operating system ABI, the binary format of object files, program libraries and so on.

  1. I was wondering whether ABI depends on both the instruction set and the OS. Are the two all that ABI depends on?
  2. What kinds of role does ABI play in different stages of compilation: preprocessing, conversion of code from C to Assembly, conversion of code from Assembly to Machine code, and linking?

    From the first quote above, it seems to me that ABI is needed for only linking stage, not the other stages. Is it correct?

  3. When is ABI needed to be considered?

    Is ABI needed to be considered during programming in C, Assembly or other languages? If yes, how are ABI and API different?

    Or is it only for linker or compiler?

  4. Is ABI specified for/in machine code, Assembly language, and/or of C?
share|improve this question

1 Answer 1

The answer from the Linux Kernel Primer is probably tailored to the Linux Kernel. The Wikipedia answer is probably more general.

On the first point, you can say for certain that the ABI depends on the platform. What "platform" means can vary - it may mean physical hardware, it may mean some kind of virtual machine, etc. The ABI may depend to some variable degree on the language and the compiler - that itself depends on the platform. Whether the ABI is partly defined by the O/S depends on how close the platform and the O/S are.

As the ABI is substantially implicit in how the generated assembler (or other code) operates, the code generation (translation from C or whatever to assembler) must be aware of the ABI. For example, the layout of the stack frame for a function call - particularly the layout of parameters - is implemented by the assembler instructions that reserve the needed space and copy the parameter values into that space.

When coding in a high level language, it is very rare to need to know the ABI in any detail, but it is sometimes necessary to specify some ABI-related options. One example, in C++ and targeting a Windows PC, is the use of calling-convention flags like pascal, stdcall and fastcall. These are often needed when linking with code written in another language or using another compiler (often operating system services), to ensure the caller ABI matches the callee ABI. More rarely, these may be specified for optimisation reasons, as e.g. some call conventions may be more efficient than others in particular circumstances.

If you are coding in assembler, and linking to operating systems or to code written in another language, you will need to use the correct ABIs for those external components. However, within your own assembler module, you are free to do what you want - in effect, to invent your own ABI, dependent only on the limitations of the real or virtual machine.

Compilers can also make up their own "custom calling conventions" where they know that a function can only be called within the same module (object file) where it is defined. This is typically done for optimisation reasons. For example, it may be possible to avoid saving registers that will not be used within that function. In a limited way, therefore, compilers can improvise an ABI.

However, this is probably an abuse of the term "ABI" - these improvised "interfaces" by definition are not at the interface of a module at all.

There are various standard conventions for various platforms. Sometimes these are strictly mandated by the platform itself - for example the ABIs used for the Java and .NET virtual machines. In other cases, the de-facto standard ABIs are defined by a particular popular compiler.

I imagine the state of ABIs on the Windows PC platform is the most complex, because of the long history with competing compilers for different languages, and with at least 32 bit Windows still supporting even ancient MS-DOS programs. But there are far older operating systems, of course, that have been used on much more varied hardware platforms - Unix being an obvious case - so I could easily be wrong about that.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.