76

I study the Linux kernel and found out that for x86_64 architecture the interrupt int 0x80 doesn't work for calling system calls1.

For the i386 architecture (32-bit x86 user-space), what is more preferable: syscall or int 0x80 and why?

I use Linux kernel version 3.4.


Footnote 1: int 0x80 does work in some cases in 64-bit code, but is never recommended. What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Alex
  • 9,891
  • 11
  • 53
  • 87
  • Where are you looking in the kernel that you're seeing the use of `int 0x80`? Can you specify some files? – Mike Oct 09 '12 at 19:01
  • @Mike Actually I found a kind of tutorial into linux kernel where as an example it was used. It was 2.6 based. – Alex Oct 09 '12 at 19:03
  • Similar to http://stackoverflow.com/q/12776340/841108 question – Basile Starynkevitch Oct 09 '12 at 19:11
  • I think `int 0x80` works on the `x86-64` kernel directly for backwards compatibility. And the Intel manual says that `syscall` is invalid in 32-bit mode. – Ciro Santilli OurBigBook.com Apr 21 '15 at 21:23
  • 1
    Complementing self: syscall is only invalid in the Intel implementation, not AMD: http://stackoverflow.com/questions/29783896/why-does-syscall-compile-in-nasm-32-bit-output-while-popa-does-not-compile-in-64 – Ciro Santilli OurBigBook.com Apr 22 '15 at 10:11
  • My answer to this question is 'ice-cream'. First, 'better' is subjective. Secondly, you don't even define a criteria by which 'better' might be evaluated by others. It's a useless question. And it's garnered a bunch of answers that are only slightly more useful than the question. – Omnifarious Jul 26 '17 at 23:44

3 Answers3

102
  • syscall is the default way of entering kernel mode on x86-64. This instruction is not available in 32 bit modes of operation on Intel processors.
  • sysenter is an instruction most frequently used to invoke system calls in 32 bit modes of operation. It is similar to syscall, a bit more difficult to use though, but that is the kernel's concern.
  • int 0x80 is a legacy way to invoke a system call and should be avoided.

The preferred way to invoke a system call is to use vDSO, a part of memory mapped in each process address space that allows to use system calls more efficiently (for example, by not entering kernel mode in some cases at all). vDSO also takes care of more difficult, in comparison to the legacy int 0x80 way, handling of syscall or sysenter instructions.

Also, see this and this.

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
Paweł Dziepak
  • 2,062
  • 1
  • 16
  • 17
  • 5
    The recommendation to choose one over the other is for OS kernel developers. Their choice is then made part of the ABI, and if you are developing for a certain OS, you must honour that ABI. For example, Linux/i386 uses int 0x80 and passes arguments in registers, whereas MirBSD/i386 uses int 0x80 and passes arguments on the stack, with one frame pointer in between (which means no setup cost in userspace when using cdecl). [This answer is mostly for people who get sent here but are not OS kernel designers.] – mirabilos Dec 06 '13 at 21:09
  • 2
    The question was about Linux and the answer describes possible means of invoking a syscall on Linux (both i386 and x86_64). You suggest that Linux/i386 uses only `int 0x80` which is not true. The preferable way to make a syscall is to use VDSO. – Paweł Dziepak Dec 11 '13 at 00:27
  • Related: [What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?](//stackoverflow.com/q/46087730). (It "works", but only with the low 32 bits of registers so you can't use it with 64-bit pointers.) – Peter Cordes May 05 '18 at 15:58
  • 1
    The VDSO is only preferred for 32-bit x86. I think x86-64 glibc uses the `syscall` ABI directly, except for system calls like `clock_gettime()` and `getpid()` where a user-space implementation is exported in the VDSO. – Peter Cordes Oct 07 '19 at 08:24
25

My answer here covers your question.

In practice, recent kernels are implementing a VDSO, notably to dynamically optimize system calls (the kernel sets the VDSO to some code best for the current processor). So you should use the VDSO, and you'll better use, for existing syscalls, the interface provided by the libc.

Notice that, AFAIK, a significant part of the cost of simple syscalls is going from user-space to kernel and back. Hence, for some syscalls (probably gettimeofday, getpid ...) the VDSO might avoid even that (and technically might avoid doing a real syscall). For most syscalls (like open, read, send, mmap ....) the kernel cost of the syscall is large enough to make any improvement of the user-space to kernel space transition (e.g. using SYSENTER or SYSCALL machine instructions instead of INT) insignificant.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 22
    Back in the 80386 days, the fastest way to enter the kernel was actually to [execute an invalid instruction](http://blogs.msdn.com/b/oldnewthing/archive/2004/12/15/313250.aspx). – Adam Rosenfield Oct 09 '12 at 19:21
  • @AdamRosenfield is [_"The hunt for a faster syscall trap"_](https://devblogs.microsoft.com/oldnewthing/20041215-00/?p=37003) the correct blog entry you were linking to? Yours has rotten... – Ruslan Mar 20 '20 at 18:43
  • @Ruslan: Yes, that's the one. Raymond Chen's blog went through a migration some time last year, and lots of old links like this one broke. – Adam Rosenfield Mar 23 '20 at 22:00
9

Beware of this before changing : system call numbers differ when doing 0x80 or syscall, e.g sys_write is 4 with 0x80 and 1 with syscall.

http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html for 32 bits or 0x80 http://blog.rchapman.org/post/36801038863/linux-system-call-table-for-x86-64 for syscall

Thomas
  • 8,306
  • 8
  • 53
  • 92
  • The question is about using `syscall` in 32-bit mode where it invokes the 32-bit ABI (only possible on AMD CPUs, and behaves differently than the 64-bit-userspace version). But yes, the 64-bit syscall ABI is different in call numbers and in calling convention. – Peter Cordes Feb 06 '20 at 09:44