32位Linux上的Syscall或sysenter?

Hib*_*u57 8 linux assembly 32-bit system-calls sysenter

从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
Run Code Online (Sandbox Code Playgroud)

我试过sysenter而不是syscall,但它以同样的方式崩溃.

Hib*_*u57 5

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

仍然是关于崩溃和核心转储的问题.我的猜测是,尽管其中任何一个syscallsysenter指令都可用作CPU指令,但可能是Linux内核在确定它在给定硬件平台上并不真正有用时,不能正确设置这个"入口点".

似乎在32位平台上,sysenter或者syscall 可能是可用的,而它始终可用,仅在64位平台上.

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

- 更新 -

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

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

调用系统调用的首选方法 由内核在引导时确定,显然此框使用sysenter.

此外,从另一个来源,一个示例FASM汇编源(如果您使用NASM需要一些翻译),通过以下方式调用系统函数linux-gate.so:在Assembly中查找linux-gate.so.1.

  • 请注意,使用 sysenter/syscall 时,约定可能与使用 int 0x80 时的约定不完全相同。对于“sysenter”,您需要在“sysenter”之前使用 iirc、“push ecx Push edx Push ebp mov ebp,esp” (2认同)
  • 请注意,由于它“由内核在启动时确定”,因此您将获得 int 80、sysenter 或 syscall,具体取决于 CPU 的功能。Int 80 始终可以工作,但速度很慢,并且在较新的 CPU 上,只有 sysenter 或 syscall 之一可以工作。这不是程序应该做出的选择,内核会为您做出最佳选择。 (2认同)

Cir*_*四事件 5

英特尔手册说,syscall是在兼容性(32比特)模式无效,因此它不应该被内核使用.

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

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