Linux 上 32 位代码中的“int 0x80”或“syscall”哪个更好?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12806584/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 14:33:44  来源:igfitidea点击:

What is better "int 0x80" or "syscall" in 32-bit code on Linux?

linuxassemblyx86system-calls32-bit

提问by Alex

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

我研究了 Linux 内核,发现对于 x86_64 架构,中断int 0x80不适用于调用系统调用1

For the i386 architecture (32-bit x86 user-space), what is more preferable: syscallor int 0x80and why?

对于 i386 架构(32 位 x86 用户空间),什么更可取:syscall或者int 0x80为什么?

I use Linux kernel version 3.4.

我使用 Linux 内核版本 3.4。



Footnote 1: int 0x80does 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?

脚注 1:int 0x80在某些情况下在 64 位代码中确实有效,但从不推荐。 如果在 64 位代码中使用 32 位 int 0x80 Linux ABI,会发生什么?

采纳答案by Pawe? Dziepak

  • syscallis default way of entering kernel mode on x86-64. This instruction is not available in 32 bit modes of operation on Intel processors.
  • sysenteris 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 kernel's concern.
  • int 0x80is a legacy way to invoke a system call and should be avoided.
  • syscall是进入内核模式的默认方式x86-64。此指令在 Intel 处理器的32 位操作模式下不可用。
  • sysenter是最常用于以 32 位操作模式调用系统调用的指令。它类似于syscall,虽然使用起来有点困难,但这是内核的关注点。
  • int 0x80是调用系统调用的传统方式,应避免使用。

Preferable way to invoke a system call is to use VDSO, a part of memory mapped in each process address space that allow 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 0x80way, handling of syscallor sysenterinstructions.

调用系统调用的首选方法是使用 VDSO,这是映射在每个进程地址空间中的一部分内存,允许更有效地使用系统调用(例如,在某些情况下根本不进入内核模式)。与传统int 0x80方式相比,VDSO 还处理更困难的处理syscallsysenter指令。

Also, see thisand this.

另外,请参阅thisthis

回答by t0mm13b

int 0x80is a better terminology to indicate its a system callto the kernel to tell it to do something.

int 0x80是一个更好的术语,表明它是对内核的系统调用,告诉它做某事。

The meaning and interpretation are interchangeble, 'make a syscall' or 'issue int 80h'.

含义和解释可以互换,“进行系统调用”或“发出 int 80h”。

It is no different to the days of DOS:

这与 DOS 时代没有什么不同:

  • invoke int 21h to get DOS to do something depedning on the AX register and optionally ES:DX register pair,
  • int 13h is the BIOS hard disk handler.
  • int 10h is the EGA/VGA screen.
  • int 09h is the keyboard handler.
  • 调用 int 21h 来让 DOS 根据 AX 寄存器和可选的 ES:DX 寄存器对做一些事情,
  • int 13h 是 BIOS 硬盘处理程序。
  • int 10h 是 EGA/VGA 屏幕。
  • int 09h 是键盘处理程序。

What is the common theme here is this, when a interrupt/syscall is invoked, the kernel checks the state of the registers to see what type of system call is required. By looking at for example, eaxregister, for example, and determine what to perform, internally context switches into kernel space, carry out the procedure and context switch back to user-space, with an option to return back the results of the call, i.e. was it successful or was it in failure.

这里的共同主题是,当调用中断/系统调用时,内核会检查寄存器的状态以查看需要哪种类型的系统调用。通过查看例如,eax注册,并确定要执行的内容,内部上下文切换到内核空间,执行过程并上下文切换回用户空间,并带有返回调用结果的选项,即是成功了还是失败了。

回答by Basile Starynkevitch

My answer herecovers 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.

在实践中,最近的内核正在实现VDSO,特别是动态优化系统调用(内核将 VDSO 设置为最适合当前处理器的代码)。因此,您应该使用 VDSO,并且对于现有的系统调用,您将更好地使用 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 SYSENTERor SYSCALLmachine instructions instead of INT) insignificant.

请注意,AFAIK,简单系统调用成本的很大一部分是从用户空间到内核再返回。因此,对于一些系统调用(可能是gettimeofdaygetpid...)的VDSO可能避免甚至是(和技术上可能会避免做一个真正的系统调用)。对于大多数系统调用(如open, read, send, mmap....),系统调用的内核开销大到足以使用户空间到内核空间转换(例如使用SYSENTERSYSCALL机器指令而不是INT)的任何改进变得无关紧要。

回答by Thomas

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

在更改之前要注意这一点:在执行 0x80 或 syscall 时,系统调用号会有所不同,例如 sys_write 是 4 与 0x80 和 1 与系统调用。

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

http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html32 位或 0x80 http://blog.rchapman.org/post/36801038863/linux-system-call-table- for-x86-64用于系统调用