X86 calling conventions

Last updated

This article describes the calling conventions used when programming x86 architecture microprocessors.

Contents

Calling conventions describe the interface of called code:

This is intimately related with the assignment of sizes and formats to programming-language types. Another closely related topic is name mangling, which determines how symbol names in the code are mapped to symbol names used by the linker. Calling conventions, type representations, and name mangling are all part of what is known as an application binary interface (ABI).

There are subtle differences in how various compilers implement these conventions, so it is often difficult to interface code which is compiled by different compilers. On the other hand, conventions which are used as an API standard (such as stdcall) are very uniformly implemented.

Historical background

The standard for IBM PC compatibles was defined by the Intel processors (8086, 80386) and the literal hardware IBM shipped. Hardware extensions and all software standards (save for a BIOS calling convention) were thrown open to market competition.

A multitude of independent software firms offered operating systems, compilers for many programming languages, and applications. Many different calling schemes were implemented by the firms, often mutually exclusive, based on different requirements, historical practices, and programmer creativity.

After the IBM compatible market shakeout, Microsoft operating systems and programming tools (with differing conventions) predominated, while second-tier firms like Borland and Novell, and open-source projects like GNU Compiler Collection (GCC), still maintained their own standards. Provisions for interoperability between vendors and products were eventually adopted, simplifying the problem of choosing a viable convention. [1]

Caller clean-up

In these types of calling conventions, the caller cleans the arguments from the stack (resets the state of the stack just as it was before the callee function was called).

cdecl

The cdecl (which stands for C declaration) is a calling convention for the programming language C and is used by many C compilers for the x86 architecture. [1] In cdecl, subroutine arguments are passed on the stack. If the return values are Integer values or memory addresses they are put into the EAX register by the callee, whereas floating point values are put in the ST0 x87 register. Registers EAX, ECX, and EDX are caller-saved, and the rest are callee-saved. The x87 floating point registers ST0 to ST7 must be empty (popped or freed) when calling a new function, and ST1 to ST7 must be empty on exiting a function. ST0 must also be empty when not used for returning a value.

In the context of the language C, function arguments are pushed on the stack in the right-to-left (RTL) order, i.e. the last argument is pushed first.

Consider the following C source code snippet:

intcallee(int,int,int);intcaller(void){returncallee(1,2,3)+5;}

On x86, it might produce the following assembly code (Intel syntax):

caller:; make new call frame; (some compilers may produce an 'enter' instruction instead)pushebp; save old call framemovebp,esp; initialize new call frame; push call arguments, in reverse; (some compilers may subtract the required space from the stack pointer,; then write each argument directly, see below.; The 'enter' instruction can also do something similar); sub esp, 12      : 'enter' instruction could do this for us; mov [ebp-4], 3   : or mov [esp+8], 3; mov [ebp-8], 2   : or mov [esp+4], 2; mov [ebp-12], 1  : or mov [esp], 1push3push2push1callcallee; call subroutine 'callee'addesp,12; remove call arguments from frameaddeax,5; modify subroutine result; (eax is the return value of our callee,; so we don't have to move it into a local variable); restore old call frame; (some compilers may produce a 'leave' instruction instead)movesp,ebp; most calling conventions dictate ebp be callee-saved,; i.e. it's preserved after calling the callee.; it therefore still points to the start of our stack frame.; we do need to make sure; callee doesn't modify (or restore) ebp, though,; so we need to make sure; it uses a calling convention which does thispopebp; restore old call frameret; return

The caller cleans the stack after the function call returns.

The cdecl calling convention is usually the default calling convention for x86 C compilers, although many compilers provide options to automatically change the calling conventions used. To manually define a function to be cdecl, some support the following syntax:

return_type__cdeclfunc_name();

Variations

There are some variations in the interpretation of cdecl. As a result, x86 programs compiled for different operating system platforms and/or by different compilers can be incompatible, even if they both use the "cdecl" convention and do not call out to the underlying environment.

Some compilers return simple data structures with a length of 2 registers or less in the register pair EAX:EDX and larger structures and class objects requiring special treatment by the exception handler (e.g., a defined constructor, destructor, or assignment) are returned in memory. To pass "in memory", the caller allocates memory and passes a pointer to it as a hidden first parameter; the callee populates the memory and returns the pointer, popping the hidden pointer when returning. [2]

In Linux, GCC sets the de facto standard for calling conventions. Since GCC version 4.5, the stack must be aligned to a 16-byte boundary when calling a function (prior versions only required a 4-byte alignment). [1] [3]

A version of cdecl is described in System V ABI for i386 systems. [4]

syscall

This is similar to cdecl in that arguments are pushed right-to-left. However, EAX, ECX, and EDX are not preserved, and the size of the parameter list in doublewords is passed in AL.

Syscall is the standard calling convention for 32 bit OS/2 API.

Arguments are pushed right-to-left. The three first (leftmost) arguments are passed in EAX, EDX, and ECX and up to four floating-point arguments are passed in ST0 through ST3, although space for them is reserved in the argument list on the stack. Results are returned in EAX or ST0. Registers EBP, EBX, ESI, and EDI are preserved.

Optlink is used by the IBM VisualAge compilers.

Callee clean-up

In these conventions, the callee cleans up the arguments from the stack. Functions which use these conventions are easy to recognize in ASM code because they will unwind the stack after returning. The x86 ret instruction allows an optional 16-bit parameter that specifies the number of stack bytes to release after returning to the caller. Such code looks like this:

ret12

Conventions named fastcall or register have not been standardized, and have been implemented differently, depending on the compiler vendor. [1] Typically register based calling conventions pass one or more arguments in registers which reduces the number of memory accesses required for the call and, thus, usually make them faster.

Pascal

Based on the Borland Turbo Pascal language's calling convention, the parameters are pushed on the stack in left-to-right (LTR) order (opposite of cdecl), and the callee is responsible for removing them from the stack.

Returning the result works as follows:

This calling convention was common in the following 16-bit APIs: OS/2 1.x, Microsoft Windows 3.x, and Borland Delphi version 1.x. Modern versions of the Windows API use stdcall, which still has the callee restoring the stack as in the Pascal convention, but the parameters are now pushed right to left.

stdcall

The stdcall [5] calling convention is a variation on the Pascal calling convention in which the callee is responsible for cleaning up the stack, but the parameters are pushed onto the stack in right-to-left order, as in the _cdecl calling convention. Registers EAX, ECX, and EDX are designated for use within the function. Return values are stored in the EAX register.

stdcall is the standard calling convention for the Microsoft Win32 API and for Open Watcom C++.

Microsoft fastcall

Microsoft __fastcall convention (aka __msfastcall[ citation needed ]) passes the first two arguments (evaluated left to right) that fit, into ECX and EDX. [6] Remaining arguments are pushed onto the stack from right to left. When the compiler compiles for IA64 or AMD64, it ignores the __fastcall keyword (or any other calling convention keyword aside from __vectorcall) and uses the Microsoft default 64-bit calling convention instead.

Other compilers like GCC, [7] Clang, [8] and ICC [ citation needed ] provide similar "fastcall" calling conventions, although they are not necessarily compatible with each other or with Microsoft fastcall. [9]

Consider the following C snippet:

__attribute__((fastcall))voidprintnums(intnum1,intnum2,intnum3){printf("The numbers you sent are: %d %d %d",num1,num2,num3);}intmain(){printnums(1,2,3);return0;}

x86 decompilation of the main function will look like (in Intel syntax):

main:; stack setuppushebpmovebp,esppush3; immediate 3 (third argument is pushed to the stack)movedx,0x2; immediate 2 (second argument) is copied to edx register.movecx,0x1; immediate 1 (first argument) is copied to ecx register.callprintnumsmoveax,0; return 0leaveretn

The first two arguments are passed in the left to right order, and the third argument is pushed on the stack. There is no stack cleanup, as stack cleanup is performed by the callee. The disassembly of the callee function is:

printnums:; stack setuppushebpmovebp,espsubesp,0x08mov[ebp-0x04],ecx; in x86, ecx = first argument.mov[ebp-0x08],edx; arg2push[ebp+0x08]; arg3 is pushed to stack.push[ebp-0x08]; arg2 is pushedpush[ebp-0x04]; arg1 is pushedpush0x8065d67; "The numbers you sent are %d %d %d"callprintf; stack cleanupaddesp,0x10nopleaveretn0x04

As the two arguments were passed through the registers and only one parameter was pushed in the stack, the pushed value is being cleared by the retn instruction, as int is 4 bytes in size in x86 systems.

Microsoft vectorcall

In Visual Studio 2013, Microsoft introduced the __vectorcall calling convention in response to efficiency concerns from game, graphic, video/audio, and codec developers. The scheme allows for larger vector types (float, double, __m128, __m256) to be passed in registers as opposed to on the stack. [10]

For IA-32 and x64 code, __vectorcall is similar to __fastcall and the original x64 calling conventions respectively, but extends them to support passing vector arguments using SIMD registers. In IA-32, the integer values are passed as usual, and the first six SIMD (XMM/YMM0-5) registers hold up to six floating-point, vector, or HVA values sequentially from left to right, regardless of actual positions caused by, e.g. an int argument appearing between them. In x64, however, the rule from the original x64 convention still apply, so that XMM/YMM0-5 only hold floating-point, vector, or HVA arguments when they happen to be the first through the sixth. [11]

__vectorcall adds support for passing homogeneous vector aggregate (HVA) values, which are composite types (structs) consisting solely of up to four identical vector types, using the same six registers. Once the registers have been allocated for vector type arguments, the unused registers are allocated to HVA arguments from left to right. The positioning rules still apply. Resulting vector type and HVA values are returned using the first four XMM/YMM registers. [11]

The Clang compiler and the Intel C++ Compiler also implement vectorcall. [12] ICC has a similar, earlier convention called __regcall; [13] it is also supported by Clang. [14]

Borland register

Evaluating arguments from left to right, it passes three arguments via EAX, EDX, ECX. Remaining arguments are pushed onto the stack, also left to right. [15] It is the default calling convention of the 32-bit compiler of Delphi, where it is known as register. This calling convention is also used by Embarcadero's C++Builder, where it is called __fastcall. [16] In this compiler, Microsoft's fastcall can be used as __msfastcall. [17]

GCC and Clang can be made to use a similar calling convention by using __stdcall with the regparm function attribute or the -mregparm=3 switch. (The stack order is inverted.) It is also possible to produce a caller clean-up variant using cdecl or extend this to also use SSE registers. [18] A cdecl-based version is used by the Linux kernel on i386 since version 2.6.20 (released February 2007). [19]

Watcom register

Watcom does not support the __fastcall keyword except to alias it to null. The register calling convention may be selected by command line switch.

Up to 4 registers are assigned to arguments in the order EAX, EDX, EBX, ECX. Arguments are assigned to registers from left to right. If any argument cannot be assigned to a register (say it is too large) it, and all subsequent arguments, are assigned to the stack. Arguments assigned to the stack are pushed from right to left. Names are mangled by adding a suffixed underscore.

Variadic functions fall back to the Watcom stack based calling convention.

The Watcom C/C++ compiler also uses the #pragma aux [20] directive that allows the user to specify their own calling convention. As its manual states, "Very few users are likely to need this method, but if it is needed, it can be a lifesaver".

TopSpeed, Clarion, JPI

The first four integer parameters are passed in registers eax, ebx, ecx and edx. Floating point parameters are passed on the floating point stack – registers st0, st1, st2, st3, st4, st5 and st6. Structure parameters are always passed on the stack. Added parameters are passed on the stack after registers are exhausted. Integer values are returned in eax, pointers in edx and floating point types in st0.

safecall

In Delphi and Free Pascal on Microsoft Windows, the safecall calling convention encapsulates COM (Component Object Model) error handling, thus exceptions aren't leaked out to the caller, but are reported in the HRESULT return value, as required by COM/OLE. When calling a safecall function from Delphi code, Delphi also automatically checks the returned HRESULT and raises an exception if needed.

The safecall calling convention is the same as the stdcall calling convention, except that exceptions are passed back to the caller in EAX as a HResult (instead of in FS:[0]), while the function result is passed by reference on the stack as though it were a final "out" parameter. When calling a Delphi function from Delphi this calling convention will appear just like any other calling convention, because although exceptions are passed back in EAX, they are automatically converted back to proper exceptions by the caller. When using COM objects created in other languages, the HResults will be automatically raised as exceptions, and the result for Get functions is in the result rather than a parameter. When creating COM objects in Delphi with safecall, there is no need to worry about HResults, as exceptions can be raised as normal but will be seen as HResults in other languages.

functionfunction_name(a:DWORD):DWORD;safecall;

Returns a result and raises exceptions like a normal Delphi function, but it passes values and exceptions as though it was:

functionfunction_name(a:DWORD;outResult:DWORD):HResult;stdcall;

Either caller or callee clean-up

thiscall

This calling convention is used for calling C++ non-static member functions. There are two primary versions of thiscall used depending on the compiler and whether or not the function uses a variable number of arguments.

For the GCC compiler, thiscall is almost identical to cdecl: The caller cleans the stack, and the parameters are passed in right-to-left order. The difference is the addition of the this pointer, which is pushed onto the stack last, as if it were the first parameter in the function prototype.

On the Microsoft Visual C++ compiler, the this pointer is passed in ECX and it is the callee that cleans the stack, mirroring the stdcall convention used in C for this compiler and in Windows API functions. When functions use a variable number of arguments, it is the caller that cleans the stack (cf. cdecl).

The thiscall calling convention can only be explicitly specified on Microsoft Visual C++ 2005 and later. On any other compiler thiscall is not a keyword. (However, disassemblers, such as IDA, must specify it. So IDA uses keyword __thiscall for this.)

Register preservation

Another part of a calling convention is which registers are guaranteed to retain their values after a subroutine call. This behavior is known as register preservation.

Caller-saved (volatile) registers

According to the Intel ABI to which the vast majority of compilers conform, the EAX, EDX, and ECX are to be free for use within a procedure or function, and need not be preserved.[ citation needed ]

As the name implies, these general-purpose registers usually hold temporary (volatile) information, that can be overwritten by any subroutine.

Therefore, it is the caller's responsibility to push each of these registers onto the stack, if it would like to restore their values after a subroutine call.

Callee-saved (non-volatile) registers

The other registers are used to hold long-lived values (non-volatile), that should be preserved across calls.

In other words, when the caller makes a procedure call, it can expect that those registers will hold the same value after the callee returns.

Thus, making it the callee's responsibility to both save (push at the start) and restore (pop accordingly) them before returning to the caller. As in the prior case, this practice should only be done on registers that the callee changes.

x86-64 calling conventions

x86-64 calling conventions take advantage of the added register space to pass more arguments in registers. Also, the number of incompatible calling conventions has been reduced. There are two in common use.

Microsoft x64 calling convention

The Microsoft x64 calling convention [21] [22] is followed on Windows and pre-boot UEFI (for long mode on x86-64). The first four arguments are placed onto the registers. That means RCX, RDX, R8, R9 (in that order) for integer, struct or pointer arguments, and XMM0, XMM1, XMM2, XMM3 for floating point arguments. Added arguments are pushed onto the stack (right to left). Integer return values (similar to x86) are returned in RAX if 64 bits or less. Floating point return values are returned in XMM0. Parameters less than 64 bits long are not zero extended; the high bits are not zeroed.

Structs and unions with sizes that match integers are passed and returned as if they were integers. Otherwise they are replaced with a pointer when used as an argument. When a return of an oversized struct is needed, another pointer to a caller-provided space is prepended as the first argument, shifting all other arguments to the right by one place. [23]

When compiling for the x64 architecture in a Windows context (whether using Microsoft or non-Microsoft tools), stdcall, thiscall, cdecl, and fastcall all resolve to using this convention.

In the Microsoft x64 calling convention, it is the caller's responsibility to allocate 32 bytes of "shadow space" on the stack right before calling the function (regardless of the actual number of parameters used), and to pop the stack after the call. The shadow space is used to spill RCX, RDX, R8, and R9, [24] but must be made available to all functions, even those with fewer than four parameters.

The registers RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile (caller-saved). [25]

The registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are considered nonvolatile (callee-saved). [25]

For example, a function taking 5 integer arguments will take the first to fourth in registers, and the fifth will be pushed on top of the shadow space. So when the called function is entered, the stack will be composed of (in ascending order) the return address, followed by the shadow space (32 bytes) followed by the fifth parameter.

In x86-64, Visual Studio 2008 stores floating point numbers in XMM6 and XMM7 (as well as XMM8 through XMM15); consequently, for x86-64, user-written assembly language routines must preserve XMM6 and XMM7 (as compared to x86 wherein user-written assembly language routines did not need to preserve XMM6 and XMM7). In other words, user-written assembly language routines must be updated to save/restore XMM6 and XMM7 before/after the function when being ported from x86 to x86-64.

Starting with Visual Studio 2013, Microsoft introduced the __vectorcall calling convention which extends the x64 convention.

System V AMD64 ABI

The calling convention of the System V AMD64 ABI is followed on Solaris, Linux, FreeBSD, macOS, [26] and is the de facto standard among Unix and Unix-like operating systems. The OpenVMS Calling Standard on x86-64 is based on the System V ABI with some extensions needed for backwards compatibility. [27] The first six integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX, R8, R9 (R10 is used as a static chain pointer in case of nested functions [28] :21), while XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6 and XMM7 are used for the first floating point arguments. [28] :22 As in the Microsoft x64 calling convention, added arguments are passed on the stack. [28] :22 Integer return values up to 64 bits in size are stored in RAX while values up to 128 bit are stored in RAX and RDX. Floating-point return values are similarly stored in XMM0 and XMM1. [28] :25 The wider YMM and ZMM registers are used for passing and returning wider values in place of XMM when they exist. [28] :26,55

Argument register overview
Argument typeRegisters
Integer/pointer arguments 1-6RDI, RSI, RDX, RCX, R8, R9
Floating point arguments 1-8XMM0 - XMM7
Excess argumentsStack
Static chain pointerR10

Struct and union parameters with sizes of two (eight in case of only SSE fields) pointers or fewer that are aligned on 64-bit boundaries are decomposed into "eightbytes" and each one is classified and passed as a separate parameter. [28] :24 Otherwise they are replaced with a pointer when used as an argument. Struct and union return types with sizes of two pointers or fewer are returned in RAX and RDX (or XMM0 and XMM1). When an oversized struct return is needed, another pointer to a caller-provided space is prepended as the first argument, shifting all other arguments to the right by one place, and the value of this pointer is returned in RAX. [28] :27

If the callee wishes to use registers RBX, RSP, RBP, and R12–R15, it must restore their original values before returning control to the caller. All other registers must be saved by the caller if it wishes to preserve their values. [28] :16

For leaf-node functions (functions which do not call any other function(s)), a 128-byte space is stored just beneath the stack pointer of the function. The space is called the red zone. This zone will not be overwritten by any signal or interrupt handlers. Compilers can thus use this zone to save local variables. Compilers may omit some instructions at the starting of the function (adjustment of RSP, RBP) by using this zone. However, other functions may overwrite this zone. Therefore, this zone should only be used for leaf-node functions. gcc and clang offer the -mno-red-zone flag to disable red-zone optimizations.

If the callee is a variadic function, then the number of floating point arguments passed to the function in vector registers must be provided by the caller in the AL register. [28] :55

Unlike the Microsoft calling convention, a shadow space is not provided; on function entry, the return address is adjacent to the seventh integer argument on the stack.

List of x86 calling conventions

This is a list of x86 calling conventions. [1] These are conventions primarily intended for C/C++ compilers (especially the 64-bit part below), and thus largely special cases. Other languages may use other formats and conventions in their implementations.

Archi­tectureNameOperating system, compilerParametersStack cleanupNotes
RegistersStack order
8086 cdeclRTL (C)Caller
Pascal LTR (Pascal)Callee
fastcall (non-member)MicrosoftAX, DX, BXLTR (Pascal)CalleeReturn pointer in BX.
fastcall (member function)MicrosoftAX, DXLTR (Pascal)Calleethis on stack low address. Return pointer in AX.
fastcall Turbo C [29] AX, DX, BXLTR (Pascal)Calleethis on stack low address. Return pointer on stack high address.
Watcom AX, DX, BX, CXRTL (C)CalleeReturn pointer in SI.
IA-32 cdeclUnix-like (GCC)RTL (C)CallerWhen returning struct/class, the calling code allocates space and passes a pointer to this space via a hidden parameter on the stack. The called function writes the return value to this address.

Stack aligned on 16-byte boundary due to a bug.

cdeclMicrosoftRTL (C)CallerWhen returning struct/class,
  • Plain old data (POD) return values 32 bits or smaller are in the EAX register
  • POD return values 33–64 bits in size are returned via the EAX:EDX registers.
  • Non-POD return values or values larger than 64-bits, the calling code will allocate space and passes a pointer to this space via a hidden parameter on the stack. The called function writes the return value to this address.

Stack aligned on 4-byte boundary.

stdcallMicrosoftRTL (C)CalleeAlso supported by GCC.
fastcallMicrosoftECX, EDXRTL (C)CalleeReturn pointer on stack if not member function. Also supported by GCC.
register Delphi, Free Pascal, Linux [30] EAX, EDX, ECXLTR (Pascal)Callee
thiscall Windows (Microsoft Visual C++)ECXRTL (C)CalleeDefault for member functions.
vectorcall Windows (Microsoft Visual C++)ECX, EDX, [XY]MM0–5 RTL (C)CalleeExtended from fastcall. Also supported by ICC and Clang. [11]
Watcom compilerEAX, EDX, EBX, ECXRTL (C)CalleeReturn pointer in ESI.
x86-64 Microsoft x64 calling convention [21] Windows (Microsoft Visual C++, GCC, Intel C++ Compiler, Delphi), UEFI RCX/XMM0, RDX/XMM1, R8/XMM2, R9/XMM3RTL (C)CallerStack aligned on 16 bytes. 32 bytes shadow space on stack. The specified 8 registers can only be used for parameters 1 through 4. For C++ classes, the hidden this parameter is the first parameter, and is passed in RCX. [31]
vectorcall Windows (Microsoft Visual C++, Clang, ICC)RCX/[XY]MM0, RDX/[XY]MM1, R8/[XY]MM2, R9/[XY]MM3 + [XY]MM4–5RTL (C)CallerExtended from MS x64. [11]
System V AMD64 ABI [28] Solaris, Linux, [32] BSD, macOS, OpenVMS (GCC, Intel C++ Compiler, Clang, Delphi)RDI, RSI, RDX, RCX, R8, R9, [XYZ]MM0–7RTL (C)CallerStack aligned on 16 bytes boundary. 128 bytes red zone below stack. The kernel interface uses RDI, RSI, RDX, R10, R8 and R9. In C++, this is the first parameter.

Related Research Articles

x86 Family of instruction set architectures

x86 is a family of complex instruction set computer (CISC) instruction set architectures initially developed by Intel based on the 8086 microprocessor and its 8-bit-external-bus variant, the 8088. The 8086 was introduced in 1978 as a fully 16-bit extension of 8-bit Intel's 8080 microprocessor, with memory segmentation as a solution for addressing more memory than can be covered by a plain 16-bit address. The term "x86" came into being because the names of several successors to Intel's 8086 processor end in "86", including the 80186, 80286, 80386 and 80486. Colloquially, their names were "186", "286", "386" and "486".

Common Intermediate Language (CIL), formerly called Microsoft Intermediate Language (MSIL) or Intermediate Language (IL), is the intermediate language binary instruction set defined within the Common Language Infrastructure (CLI) specification. CIL instructions are executed by a CIL-compatible runtime environment such as the Common Language Runtime. Languages which target the CLI compile to CIL. CIL is object-oriented, stack-based bytecode. Runtimes typically just-in-time compile CIL instructions into native code.

<span class="mw-page-title-main">Application binary interface</span> Binary interface between two program units

In computer software, an application binary interface (ABI) is an interface between two binary program modules. Often, one of these modules is a library or operating system facility, and the other is a program that is being run by a user.

Bytecode is a form of instruction set designed for efficient execution by a software interpreter. Unlike human-readable source code, bytecodes are compact numeric codes, constants, and references that encode the result of compiler parsing and performing semantic analysis of things like type, scope, and nesting depths of program objects.

A low-level programming language is a programming language that provides little or no abstraction from a computer's instruction set architecture; commands or functions in the language are structurally similar to a processor's instructions. Generally, this refers to either machine code or assembly language. Because of the low abstraction between the language and machine language, low-level languages are sometimes described as being "close to the hardware". Programs written in low-level languages tend to be relatively non-portable, due to being optimized for a certain type of system architecture.

x86 assembly language is the name for the family of assembly languages which provide some level of backward compatibility with CPUs back to the Intel 8008 microprocessor, which was launched in April 1972. It is used to produce object code for the x86 class of processors.

The x86 instruction set refers to the set of instructions that x86-compatible microprocessors support. The instructions are usually part of an executable program, often stored as a computer file and executed on the processor.

In computer programming, an inline assembler is a feature of some compilers that allows low-level code written in assembly language to be embedded within a program, among code that otherwise has been compiled from a higher-level language such as C or Ada.

In computer science, a tail call is a subroutine call performed as the final action of a procedure. If the target of a tail is the same subroutine, the subroutine is said to be tail recursive, which is a special case of direct recursion. Tail recursion is particularly useful, and is often easy to optimize in implementations.

The Thread Information Block (TIB) or Thread Environment Block (TEB) is a data structure in Win32 on x86 that stores information about the currently running thread. It descended from, and is backward-compatible on 32-bit systems with, a similar structure in OS/2.

In computer science, a call stack is a stack data structure that stores information about the active subroutines of a computer program. This type of stack is also known as an execution stack, program stack, control stack, run-time stack, or machine stack, and is often shortened to simply the "stack". Although maintenance of the call stack is important for the proper functioning of most software, the details are normally hidden and automatic in high-level programming languages. Many computer instruction sets provide special instructions for manipulating stacks.

In computer science, a calling convention is an implementation-level (low-level) scheme for how subroutines or functions receive parameters from their caller and how they return a result. When some code calls a function, design choices have been taken for where and how parameters are passed to that function, and where and how results are returned from that function, with these transfers typically done via certain registers or within a stack frame on the call stack. There are design choices for how the tasks of preparing for a function call and restoring the environment after the function has completed are divided between the caller and the callee. Some calling convention specifies the way every function should get called. The correct calling convention should be used for every function call, to allow the correct and reliable execution of the whole program using these functions.

In assembly language programming, the function prologue is a few lines of code at the beginning of a function, which prepare the stack and registers for use within the function. Similarly, the function epilogue appears at the end of the function, and restores the stack and registers to the state they were in before the function was called.

In computer programming, the term hooking covers a range of techniques used to alter or augment the behaviour of an operating system, of applications, or of other software components by intercepting function calls or messages or events passed between software components. Code that handles such intercepted function calls, events or messages is called a hook.

A86 is an assembler for MS-DOS which generates code for the Intel x86 family of microprocessors. Written by Eric Isaacson, it was first made available as shareware in June 1986. The assembler is contained in one 32K executable and can directly produce a COM file or an object file for use with a standard linker. It comes with a debugger, D86.

In the x86 architecture, the CPUID instruction is a processor supplementary instruction allowing software to discover details of the processor. It was introduced by Intel in 1993 with the launch of the Pentium and SL-enhanced 486 processors.

crt0 is a set of execution startup routines linked into a C program that performs any initialization work required before calling the program's main function. After the main function completes the control returns to crt0, which calls the library function exit(0) to terminate the process.

<span class="mw-page-title-main">Cosmos (operating system)</span> Toolkit for building GUI and command-line based operating systems

C# Open Source Managed Operating System (Cosmos) is a toolkit for building GUI and command-line based operating systems, written mostly in the programming language C# and small amounts of a high-level assembly language named X#. Cosmos is a backronym, in that the acronym was chosen before the meaning. It is open-source software released under a BSD license.

JIT spraying is a class of computer security exploit that circumvents the protection of address space layout randomization and data execution prevention by exploiting the behavior of just-in-time compilation. It has been used to exploit the PDF format and Adobe Flash.

In computer programming, a function is a callable unit of software logic that has a well-defined interface and behavior and can be invoked multiple times.

References

Footnotes

  1. 1 2 3 4 5 Fog, Agner (2010-02-16). Calling conventions for different C++ compilers and operating systems (PDF).
  2. Pollard, Jonathan de Boyne (2010). "The gen on function calling conventions". Frequently Given Answers.
  3. "GCC Bugzilla – Bug 40838 - gcc shouldn't assume that the stack is aligned". 2009.
  4. "System V Application Binary Interface: Intel 386 Architecture Processor Supplement" (PDF) (4th ed.).
  5. "__stdcall (C++)". MSDN. Microsoft. Archived from the original on 2008-04-10. Retrieved 2019-02-13.
  6. "__fastcall". MSDN. Retrieved 2013-09-26.
  7. Ohse, Uwe. "gcc attribute overview: function fastcall". ohse.de. Retrieved 2010-09-27.
  8. "Attributes in Clang: fastcall". Clang Documentation. 2022. Retrieved 15 December 2022.
  9. Patocka, Mikulas (11 August 2009). "Fastcall calling convention is incompatible with Windows" . Retrieved 15 December 2022.
  10. "Introducing 'Vector Calling Convention'". MSDN. 11 July 2013. Retrieved 2014-12-31.
  11. 1 2 3 4 "__vectorcall". MSDN. Retrieved 2014-12-31.
  12. "Attributes in Clang: vectorcall". Clang Documentation. 2022. Retrieved 15 December 2022.
  13. "C/C++ Calling Conventions". 16 December 2022. Retrieved 15 December 2022.
  14. "_vectorcall and __regcall demystified". software.intel.com. 7 June 2017.
  15. "Program Control: Register Convention". docwiki.embarcadero.com. 2010-06-01. Retrieved 2010-09-27.
  16. "_fastcall, __fastcall". docwiki.embarcadero.com.
  17. "__msfastcall". docwiki.embarcadero.com.
  18. "x86 Function Attributes". Using the GNU Compiler Collection (GCC).
  19. "i386: always enable regparm".
  20. "Calling_Conventions: Specifying_Calling_Conventions_the_Watcom_Way". openwatcom.org. 2010-04-27. Archived from the original on 2021-03-08. Retrieved 2018-08-31.
  21. 1 2 "x64 Software Conventions: Calling Conventions". msdn.microsoft.com. 2010. Retrieved 2010-09-27.
  22. "x64 Architecture". msdn.microsoft.com. 6 January 2023.
  23. "x64 Calling Convention: Return Values". docs.microsoft.com. Retrieved 2020-01-17.
  24. "x64 Software Conventions - Stack Allocation". Microsoft. Retrieved 2010-03-31.
  25. 1 2 "Caller/Callee Saved Registers". Microsoft Docs. Microsoft. 18 May 2022.
  26. "x86-64 Code Model". Mac Developer Library. Apple Inc. Archived from the original on 2016-03-10. Retrieved 2016-04-06. The x86-64 environment in OS X has only one code model for user-space code. It is most similar to the small PIC model defined by the x86-64 System V ABI.
  27. "VSI OpenVMS Calling Standard" (PDF). vmssoftware.com. May 2020. Retrieved 2020-12-21.
  28. 1 2 3 4 5 6 7 8 9 10 Lu, H.J.; Matz, Michael; Girkar, Milind; Hubička, Jan; Jaeger, Andreas; Mitchell, Mark, eds. (2023-05-23). "System V Application Binary Interface: AMD64 Architecture Processor Supplement (With LP64 and ILP32 Programming Models) Version 1.0" (PDF). GitLab . 1.0.
  29. Borland C/C++ version 3.1 User Guide (PDF). Borland. 1992. pp. 158, 189–191.
  30. "Linux 32-bit Calling Conventions" . Retrieved 22 April 2024.
  31. "Register Usage". Microsoft Docs. Microsoft. Archived from the original on 15 September 2017. Retrieved 15 September 2017.
  32. "Linux 64-bit Calling Conventions" . Retrieved 22 April 2024.

Other sources

Further reading