【问题标题】:In Linux x86_64 are syscalls and int 0x80 related?在 Linux x86_64 中,系统调用和 int 0x80 相关吗?
【发布时间】:2015-06-09 00:25:55
【问题描述】:

我知道在 Linux x64 中,“syscall”和“int 0x80”汇编指令会在软件中产生一个中断,要求内核做一些工作。它们有不同的操作码(0F 05 vs CD 80),前者更快。
我不清楚他们之间是否有任何关系:他们真的独立吗? (即:“系统调用”是否调用“int 0x80”?) 谢谢。

【问题讨论】:

  • 我不知道有什么区别,但是两者都在 64 位长模式下工作,而只有 int 0x80 在 32 位模式下工作,这表明无论前者做什么不仅效率更高,而且不使用相同的 32 位 CPU 功能。我怀疑这与 64 位长模式具有非常简化的平面内存模型(32 位是分段的)这一事实有关。
  • 在 64 位代码中,只能使用 syscall。有关如何(以及如何在 32 位代码中使用 int 0x80)的详细信息,请参阅 stackoverflow.com/questions/2535989/…
  • int 0x80 即使在 64 位进程中执行时也会调用 32 位 ABI(及其调用约定和系统调用号)。这绝不是一个好主意,也没有任何好处(syscall 更快)。例如eax=1 / int 0x80 是 sys_exit(),但 eax=1 / syscall 是 sys_write()。 stackoverflow.com/questions/2500362/…

标签: linux system-calls


【解决方案1】:

int 0x80 传闻已过时(因为速度慢)。顺便说一句,你真的很想使用vdso(7)

AFAIK,两条指令都进入内核,每个指令都有一些(短)内核处理序列,最终跳转到系统调用表中。

【讨论】:

  • 谢谢。那么我应该查看内核代码以找出差异吗?
  • 是的,但你为什么真正关心?为什么不使用 VDSO?
  • 我对很多关于这个东西的摘要文档感到困惑,特别是关于“系统调用”和“int 0x80”,所以我问了一些问题。
【解决方案2】:

int 0x80 是与8086 - 80386 程序集一起使用的32-bit 中断。 x86_64 使用 syscall 代替它。请参阅 /usr/include/asm/unistd_32.hunistd_64.h 中的差异,了解各自期望调用各种内核函数的不同调用号。

【讨论】:

  • "int 0x80" 也适用于 x64。在 x86 中有 sysenter;所以问题是一样的:sysenter和int 0x80之间有关系吗?
【解决方案3】:

syscall (x86-64) 和 sysenter (x86-32) 指令更新更快,因此在可用时使用;但保留int 0x80 机制是为了与旧的二进制文件兼容。没有语义差异——无论使用哪条指令将控制权转移到内核,系统调用编号都是相同的,而且我认为参数也都在相同的位置。

我模糊地记得有少数系统调用只能使用int 0x80 进行,因为它们与堆栈相关的行为异常(克隆?执行?sigreturn?),但这可能不再正确。

【讨论】:

  • 相关:What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?int 0x80 是 32 位 ABI(带有 32 位索书号和寄存器),即使您从 64 位用户空间使用它也是如此。 (strace 解码错误,就好像它是syscall。也许这就是为什么您的答案错误地声称您如何进入内核并不重要?)
猜你喜欢
  • 1970-01-01
  • 2014-04-22
  • 2012-12-11
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 2012-08-23
相关资源
最近更新 更多