从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
,但它以同样的方式崩溃。
经过一些网络搜索,我在StackOverflow上找到了另一个主题:Linux通过系统发送器教程调用系统调用。它说,建议调用系统的方法,既不是使用int 80h
,也不是使用syscall
或sysenter
,而是使用linux-gate.so
。
仍然存在关于崩溃和核心转储的问题。我的猜测是,虽然syscall
或sysenter
指令都可以作为CPU指令,但可能是Linux内核没有正确设置这个"入口点",当它决定它在给定的硬件平台上不是真正有用的时候。
似乎在32位平台上,sysenter
或syscall
可能可用,而它总是可用的,只有在64位平台上。
虽然我觉得这回答了我的问题,但我仍然欢迎更多的材料,像一个权威的参考,为我的上述猜测。
——update——
至少,我能找到这个来证实上面的说法。这仍然不是一个权威的参考,但我相信似乎足够可信。
linux-gate.so.1是什么?说:
调用系统调用的首选方式是由内核在引导时确定,以及显然这个盒子使用了系统发送器。
另外,从另一个源,一个示例FASM汇编源(如果使用NASM需要一些翻译),通过linux-gate.so
调用系统函数:查找linux-gate.so。
Intel手册说syscall
在兼容(32位)模式下是无效的,所以内核不应该使用它。
这似乎是一个英特尔的限制然而:https://stackoverflow.com/a/29784932/895245 AMD没有,但肯定Linux必须支持英特尔:-)
sysenter
似乎是目前最好的方法,因为它比int 0x80
更快,但它应该通过VDSO间接使用,正如如何在内联汇编中通过系统发送器调用系统调用(x86/amd64 linux)中所解释的那样?