9

从 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,但它以同样的方式崩溃。

4

2 回答 2

6

英特尔手册说这syscall在兼容(32位)模式下无效,因此内核不应使用它。

然而,这似乎是英特尔独有的限制:https ://stackoverflow.com/a/29784932/895245 AMD 没有,但 Linux 肯定必须支持英特尔 :-)

sysenter似乎是今天最好的方法,因为它比 快int 0x80,但它应该通过 VDSO 间接使用,如如何通过内联汇编中的 sysenter 调用系统调用(x86/amd64 linux)?

于 2015-04-21T22:42:58.540 回答
6

经过一些网络搜索,我找到了 StackOverflow 上的另一个主题:Linux 通过 sysenter 教程调用系统调用。它说调用系统的推荐方法既不是 usingint 80h也不syscallsysenter,而是linux-gate.so

关于崩溃和核心转储的问题仍然存在。最后我的猜测是,尽管其中一个syscall或多个sysenter指令都可以作为 CPU 指令使用,但可能是 Linux 内核在确定它在给定的硬件平台上没有真正用处时没有正确设置这个“入口点”。

似乎在 32 位平台上,sysenter或者syscall 可能可用,虽然它始终可用,但仅在 64 位平台上。

虽然我觉得这回答了我的问题,但我仍然欢迎更多材料,比如我上述猜测的权威参考。

- 更新 -

至少,我可以找到这证实了上述内容。这仍然不是一个权威的参考,但我相信它似乎足够可信。

什么是 linux-gate.so.1?,说:

调用系统调用的首选方式 由内核在启动时确定,显然这个框使用 sysenter。

此外,从另一个来源,一个示例 FASM 程序集源(如果您使用 NASM,需要一些翻译),通过以下方式调用系统函数linux-gate.soFinding linux-gate.so.1 in Assembly

于 2013-03-24T15:44:02.360 回答