从MS-DOS开始,我知道使用中断的系统调用。在旧论文中,我看到了引用int 80h
来调用Linux上的系统函数。由于现在相当长的一段时间,我知道int 80h
已被弃用,而赞成syscall
指令。但我无法让它在我的32位机器上工作。
syscall
指令只能在64位平台上使用吗? 32位Linux是否使用syscall
?
在我的32位Linux(Ubuntu Precise)上,该程序终止于核心转储:
global _start
_start:
mov eax, 4 ; 4 is write
mov ebx, 1 ; 1 is stdout
mov ecx, message ; address of string
mov edx, length ; number of bytes
syscall
mov eax, 1 ; 1 is exit
xor ebx, ebx ; return code 0
syscall
message:
db 10,"Hello, World",10,10
length equ $ - message
我尝试使用sysenter
代替syscall
,但它的崩溃方式相同。
答案 0 :(得分:5)
经过一些网络搜索后,我在StackOverflow上找到了另一个主题:Linux invoke a system call via sysenter tutorial。它说调用系统的推荐方法既不是int 80h
也不是syscall
,也不是sysenter
,而是linux-gate.so
。
仍然是关于崩溃和核心转储的问题。我的猜测终于虽然syscall
或sysenter
指令可用作CPU指令,但可能是Linux内核在确定它不是真正有用的时候没有正确设置这个“入口点”在给定的硬件平台上。
似乎在32位平台上,sysenter
或syscall
可能可用,而它始终可用,仅在64位平台上可用。
虽然我觉得这回答了我的问题,但我仍然欢迎更多的材料,比如我上面猜测的权威参考。
- 更新 -
至少,我能找到证实以上内容的。这仍然不是一个权威的参考,但我相信它似乎足够可信。
调用系统调用的首选方法是 由内核在启动时确定,以及 显然这个盒子使用sysenter。
此外,从另一个来源,一个示例FASM程序集源(如果您使用NASM需要一些翻译),通过linux-gate.so
调用系统函数:Finding linux-gate.so.1 in Assembly 。
答案 1 :(得分:5)
Intel manual表示syscall
在兼容性(32位)模式下无效,因此内核不应使用它。
这似乎只是英特尔的限制:AMD没有https://stackoverflow.com/a/29784932/895245,但Linux必须支持英特尔: - )
sysenter
似乎是今天最好的方式,因为它比int 0x80
更快,但它应该通过VDSO间接使用,如How to invoke a system call via sysenter in inline assembly (x86/amd64 linux)?所述