在Linux x86_64中,系统调用和int 0x80有关吗?

7
我知道在Linux x64中,“syscall”和“int 0x80”汇编指令会生成一个软件中断,请求内核执行一些工作。它们具有不同的操作码(0F 05与CD 80),前者更快。
对我来说并不清楚它们之间是否存在任何关系:它们真的是独立的吗?(即:“syscall”是否调用“int 0x80”?) 谢谢。

我不知道它们之间的区别是什么,但两者都可以在64位长模式下工作,而只有int 0x80可以在32位模式下工作,这表明前者所做的事情不仅更有效率,而且不会使用相同的32位CPU特性。我怀疑这与64位长模式具有简化的平面内存模型有关(32位是分段的)。 - teppic
在64位代码中,只能使用syscall。有关如何使用(以及如何在32位代码中使用int 0x80)的详细信息,请参见https://dev59.com/Q3E85IYBdhLWcg3w8IXK。 - Peter Cordes
1
即使在64位进程中执行,int 0x80调用32位ABI(具有其调用约定和系统调用号)。这从来不是一个好主意,也没有任何好处(syscall更快)。例如,eax=1 / int 0x80是sys_exit(),但eax=1 / syscall是sys_write()。https://dev59.com/knE95IYBdhLWcg3wApHl#46020177 - Peter Cordes
3个回答

6
syscall (x86-64) 和 sysenter (x86-32) 指令是较新且更快的,因此在可用时会使用它们;但 int 0x80 机制被保留以与旧二进制文件兼容。没有语义差异--无论使用哪个指令将控制转移至内核,系统调用编号都是相同的,我认为参数也都在相同的位置。我模糊地记得有一些系统调用由于其不寻常的堆栈相关行为(clone?execve?sigreturn?)而只能使用int 0x80 进行调用,但这可能已不再正确。

相关:**如果在64位代码中使用32位int 0x80 Linux ABI会发生什么?**。即使从64位用户空间使用,int 0x80仍然是32位ABI(具有32位调用号和寄存器)。 (strace解码错误,好像它是syscall。也许这就是为什么您的答案错误地声称如何进入内核并不重要的原因?) - Peter Cordes

1
"

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

据我所知,这两个指令都会进入内核,并且每个指令都有一些(短)的内核处理序列,最终跳转到系统调用表中。

"

谢谢。那我应该查看内核代码来找到区别吗? - Antonio Rizzo
是的,但你真的在意吗?为什么不使用VDSO呢? - Basile Starynkevitch
我对许多关于这方面的摘要文件感到困惑,特别是关于“syscall”和“int 0x80”的部分,所以我想请教一下。 - Antonio Rizzo

1
"

int 0x80是与8086 - 80386汇编配合使用的32位中断。在x86_64中,使用syscall代替。请查看/usr/include/asm/unistd_32.hunistd_64.h中的差异,以了解它们各自期望调用哪些内核函数。

"

"int 0x80" 在 x64 中也可以使用。在 x86 中有 sysenter;因此问题是一样的:sysenter 和 int 0x80 之间是否存在关联? - Antonio Rizzo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接