What are the calling conventions for UNIX & Linux system calls (and user-space functions) on i386 and x86-64

claws :

Following links explain x86-32 system call conventions for both UNIX (BSD flavor) & Linux:

But what are the x86-64 system call conventions on both UNIX & Linux?

claws :

Further reading for any of the topics here: The Definitive Guide to Linux System Calls


I verified these using GNU Assembler (gas) on Linux.

Kernel Interface

x86-32 aka i386 Linux System Call convention:

In x86-32 parameters for Linux system call are passed using registers. %eax for syscall_number. %ebx, %ecx, %edx, %esi, %edi, %ebp are used for passing 6 parameters to system calls.

The return value is in %eax. All other registers (including EFLAGS) are preserved across the int $0x80.

I took following snippet from the Linux Assembly Tutorial but I'm doubtful about this. If any one can show an example, it would be great.

If there are more than six arguments, %ebx must contain the memory location where the list of arguments is stored - but don't worry about this because it's unlikely that you'll use a syscall with more than six arguments.

For an example and a little more reading, refer to http://www.int80h.org/bsdasm/#alternate-calling-convention. Another example of a Hello World for i386 Linux using int 0x80: Hello, world in assembly language with Linux system calls?

There is a faster way to make 32-bit system calls: using sysenter. The kernel maps a page of memory into every process (the vDSO), with the user-space side of the sysenter dance, which has to cooperate with the kernel for it to be able to find the return address. Arg to register mapping is the same as for int $0x80. You should normally call into the vDSO instead of using sysenter directly. (See The Definitive Guide to Linux System Calls for info on linking and calling into the vDSO, and for more info on sysenter, and everything else to do with system calls.)

x86-32 [Free|Open|Net|DragonFly]BSD UNIX System Call convention:

Parameters are passed on the stack. Push the parameters (last parameter pushed first) on to the stack. Then push an additional 32-bit of dummy data (Its not actually dummy data. refer to following link for more info) and then give a system call instruction int $0x80

http://www.int80h.org/bsdasm/#default-calling-convention


x86-64 Linux System Call convention:

x86-64 Mac OS X is similar but different. TODO: check what *BSD does.

Refer to section: "A.2 AMD64 Linux Kernel Conventions" of System V Application Binary Interface AMD64 Architecture Processor Supplement. The latest versions of the i386 and x86-64 System V psABIs can be found linked from this page in the ABI maintainer's repo. (See also the tag wiki for up-to-date ABI links and lots of other good stuff about x86 asm.)

Here is the snippet from this section:

  1. User-level applications use as integer registers for passing the sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9. The kernel interface uses %rdi, %rsi, %rdx, %r10, %r8 and %r9.
  2. A system-call is done via the syscall instruction. This clobbers %rcx and %r11 as well as the %rax return value, but other registers are preserved.
  3. The number of the syscall has to be passed in register %rax.
  4. System-calls are limited to six arguments, no argument is passed directly on the stack.
  5. Returning from the syscall, register %rax contains the result of the system-call. A value in the range between -4095 and -1 indicates an error, it is -errno.
  6. Only values of class INTEGER or class MEMORY are passed to the kernel.

Remember this is from the Linux-specific appendix to the ABI, and even for Linux it's informative not normative. (But it is in fact accurate.)

This 32-bit int $0x80 ABI is usable in 64-bit code (but highly not recommended). What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code? It still truncates its inputs to 32-bit, so it's unsuitable for pointers, and it zeros r8-r11.

User Interface: function calling

x86-32 Function Calling convention:

In x86-32 parameters were passed on stack. Last parameter was pushed first on to the stack until all parameters are done and then call instruction was executed. This is used for calling C library (libc) functions on Linux from assembly.

Modern versions of the i386 System V ABI (used on Linux) require 16-byte alignment of %esp before a call, like the x86-64 System V ABI has always required. Callees are allowed to assume that and use SSE 16-byte loads/stores that fault on unaligned. But historically, Linux only required 4-byte stack alignment, so it took extra work to reserve naturally-aligned space even for an 8-byte double or something.

Some other modern 32-bit systems still don't require more than 4 byte stack alignment.


x86-64 System V user-space Function Calling convention:

x86-64 System V passes args in registers, which is more efficient than i386 System V's stack args convention. It avoids the latency and extra instructions of storing args to memory (cache) and then loading them back again in the callee. This works well because there are more registers available, and is better for modern high-performance CPUs where latency and out-of-order execution matter. (The i386 ABI is very old).

In this new mechanism: First the parameters are divided into classes. The class of each parameter determines the manner in which it is passed to the called function.

For complete information refer to : "3.2 Function Calling Sequence" of System V Application Binary Interface AMD64 Architecture Processor Supplement which reads, in part:

Once arguments are classified, the registers get assigned (in left-to-right order) for passing as follows:

  1. If the class is MEMORY, pass the argument on the stack.
  2. If the class is INTEGER, the next available register of the sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9 is used

So %rdi, %rsi, %rdx, %rcx, %r8 and %r9 are the registers in order used to pass integer/pointer (i.e. INTEGER class) parameters to any libc function from assembly. %rdi is used for the first INTEGER parameter. %rsi for 2nd, %rdx for 3rd and so on. Then call instruction should be given. The stack (%rsp) must be 16B-aligned when call executes.

If there are more than 6 INTEGER parameters, the 7th INTEGER parameter and later are passed on the stack. (Caller pops, same as x86-32.)

The first 8 floating point args are passed in %xmm0-7, later on the stack. There are no call-preserved vector registers. (A function with a mix of FP and integer arguments can have more than 8 total register arguments.)

Variadic functions (like printf) always need %al = the number of FP register args.

There are rules for when to pack structs into registers (rdx:rax on return) vs. in memory. See the ABI for details, and check compiler output to make sure your code agrees with compilers about how something should be passed/returned.


Note that the Windows x64 function calling convention has multiple significant differences from x86-64 System V, like shadow space that must be reserved by the caller (instead of a red-zone), and call-preserved xmm6-xmm15. And very different rules for which arg goes in which register.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Java

What are the calling conventions for UNIX & Linux system calls on i386 and x86-64

From Dev

What is the difference between x86_64 and i386?

From Java

Why do x86-64 Linux system calls modify RCX, and what does the value mean?

From Dev

What is the user space virtual memory layout for x86_64 Linux process?

From Dev

What do x86_64, i386, ia64 and other such jargons stand for?

From Dev

Why does the i386 version of software get installed on an x86_64 system?

From Dev

Assemble and run i386 asm program on x86-64 Linux with as and ld

From Dev

What determines if a 32-bit library built on a 64-bit machine needs x86_64 or i386 dependencies?

From Dev

What versions of linux work on Dell dimension 4600 i386 system

From Dev

Why do Linux world use the term i386 instead of x86?

From Dev

Why are Linux system call numbers in x86 and x86_64 different?

From Dev

Could not launch './qemu/linux-x86_64/qemu-system-i386': No such file or directory

From Dev

Why does the iOS simulator require i386 and x86_64 symbols even though I'm on an x86_64 system only?

From Dev

What is the explanation of this x86 Hello World using 32-bit int 0x80 Linux system calls from _start?

From Dev

x86 assembly gcc calling conventions esp register

From Dev

Assembly x86 - Calling C functions

From Java

difference between i386:x64-32 vs i386 vs i386:x86_64

From Java

Is it possible to create threads without system calls in Linux x86 GAS assembly?

From Dev

How do I convert a x86 RPM to a x86 DEB within a x64 system?

From Dev

Why do x86-64 Linux system calls work with 6 registers set?

From Dev

How to properly pass buffer pointers to Linux system calls in x86_64 assembly?

From Dev

Complications of having architecture i386 in 64 bit system?

From Java

GDB error: Selected architecture i386 is not compatible with reported target architecture i386:x86-64

From

What is the difference between the Intel x86 Atom and Atom_64 system images?

From Dev

What are differences between linux kernel compiled for generic x86/64 vs Xeon or others

From Dev

Ubuntu 14.10 x64 and i386

From Dev

Should I mention calling conventions in pure virtual functions?

From

Should I choose x86_64 for testing rather than the "recommended" x86 for virtual device system image?

From Dev

How can I build a rpm for i386 target on a x86-64 machine?

Related Related

  1. 1

    What are the calling conventions for UNIX & Linux system calls on i386 and x86-64

  2. 2

    What is the difference between x86_64 and i386?

  3. 3

    Why do x86-64 Linux system calls modify RCX, and what does the value mean?

  4. 4

    What is the user space virtual memory layout for x86_64 Linux process?

  5. 5

    What do x86_64, i386, ia64 and other such jargons stand for?

  6. 6

    Why does the i386 version of software get installed on an x86_64 system?

  7. 7

    Assemble and run i386 asm program on x86-64 Linux with as and ld

  8. 8

    What determines if a 32-bit library built on a 64-bit machine needs x86_64 or i386 dependencies?

  9. 9

    What versions of linux work on Dell dimension 4600 i386 system

  10. 10

    Why do Linux world use the term i386 instead of x86?

  11. 11

    Why are Linux system call numbers in x86 and x86_64 different?

  12. 12

    Could not launch './qemu/linux-x86_64/qemu-system-i386': No such file or directory

  13. 13

    Why does the iOS simulator require i386 and x86_64 symbols even though I'm on an x86_64 system only?

  14. 14

    What is the explanation of this x86 Hello World using 32-bit int 0x80 Linux system calls from _start?

  15. 15

    x86 assembly gcc calling conventions esp register

  16. 16

    Assembly x86 - Calling C functions

  17. 17

    difference between i386:x64-32 vs i386 vs i386:x86_64

  18. 18

    Is it possible to create threads without system calls in Linux x86 GAS assembly?

  19. 19

    How do I convert a x86 RPM to a x86 DEB within a x64 system?

  20. 20

    Why do x86-64 Linux system calls work with 6 registers set?

  21. 21

    How to properly pass buffer pointers to Linux system calls in x86_64 assembly?

  22. 22

    Complications of having architecture i386 in 64 bit system?

  23. 23

    GDB error: Selected architecture i386 is not compatible with reported target architecture i386:x86-64

  24. 24

    What is the difference between the Intel x86 Atom and Atom_64 system images?

  25. 25

    What are differences between linux kernel compiled for generic x86/64 vs Xeon or others

  26. 26

    Ubuntu 14.10 x64 and i386

  27. 27

    Should I mention calling conventions in pure virtual functions?

  28. 28

    Should I choose x86_64 for testing rather than the "recommended" x86 for virtual device system image?

  29. 29

    How can I build a rpm for i386 target on a x86-64 machine?

HotTag

Archive