我研究了Linux内核并发现针对x86_64架构,中断int 0x80
不能用于调用系统调用1。
对于i386架构(32位x86用户空间),更适合使用syscall
或int 0x80
?为什么?
我使用的是Linux内核版本3.4。
注脚1:int 0x80
在某些情况下可以在64位代码中工作,但不建议使用。 如果在64位代码中使用32位int 0x80 Linux ABI会发生什么?
我研究了Linux内核并发现针对x86_64架构,中断int 0x80
不能用于调用系统调用1。
对于i386架构(32位x86用户空间),更适合使用syscall
或int 0x80
?为什么?
我使用的是Linux内核版本3.4。
注脚1:int 0x80
在某些情况下可以在64位代码中工作,但不建议使用。 如果在64位代码中使用32位int 0x80 Linux ABI会发生什么?
syscall
是在 x86-64
上进入内核模式的默认方式。但是这条指令在 Intel 处理器的 32 位操作模式下不可用。sysenter
是在 32 位操作模式下最常用于调用系统调用的指令。它与 syscall
类似,但使用起来稍微困难一些,不过这是内核的问题。int 0x80
是一个遗留的调用系统调用的方式,应该避免使用。调用系统调用的首选方式是使用 vDSO,它是每个进程地址空间中映射的一部分内存,允许更有效地使用系统调用(例如,在某些情况下根本不需要进入内核模式)。相对于传统的 int 0x80
方式,vDSO 还可以处理更困难的 syscall
或 sysenter
指令。
int 0x80
,但这是不正确的。更好的方式是使用VDSO来进行系统调用。 - Paweł Dziepaksyscall
ABI,除了像clock_gettime()
和getpid()
这样的系统调用,在VDSO中导出用户空间实现。 - Peter Cordes我的回答 在这里 涵盖了你的问题。
实际上,最近的内核正在实现一个VDSO,尤其是为了动态优化系统调用(内核将VDSO设置为适合当前处理器的某个代码)。 因此,您应该使用VDSO,并且最好使用libc提供的接口来使用现有的系统调用。
请注意,据我所知,简单系统调用的大部分成本都是从用户空间到内核空间再返回。 因此,对于某些系统调用(可能包括gettimeofday
、getpid
等),VDSO甚至可以避免这种情况(并且从技术上讲,可能避免进行真正的系统调用)。 对于大多数系统调用(例如open
、read
、send
、mmap
等),系统调用的内核成本足够大,以至于任何改进从用户空间到内核空间转换的方法(例如使用SYSENTER
或SYSCALL
机器指令而不是INT
)都不重要。
syscall
,其中它调用32位ABI(仅在AMD CPU上可能,并且与64位用户空间版本的行为不同)。但是,是的,64位syscall ABI在调用号码和调用约定方面不同。 - Peter Cordes
int 0x80
的使用?能具体指出一些文件吗? - Mikeint 0x80
直接在x86-64
内核上向后兼容。而英特尔手册指出,在32位模式下syscall
是无效的。 - Ciro Santilli OurBigBook.com