英特尔 CPU 上的 SYSENTER

SYSENTER on Intel CPUs

所以 AFAIK syscall 指令,是 AMD 的等同于 sysenter。所以理论上应该只能在 AMD 芯片上找到一条 syscall 指令,对吧?好吧,显然情况并非如此,因为我在搞乱 ntdll.dll 和 ntdll.dll(WOW64 版本),我发现常规版本使用 syscall 而 ntdll.dll 来自 WOW64 使用 sysenter。这是为什么?

所有 x86-64 CPUs 支持 syscall 64 位模式;这是进行 64 位系统调用的唯一方法。

32 位代码使用 CPU 支持的任何比 int 更快的代码。


您关于仅支持 AMD syscall 的信息是正确的仅在 32 位用户-space 模式下(传统和兼容模式)。

Intel的sysenter成为32位用户的首选-space;英特尔赢得了主导地位的斗争。此外,显然 AMD 的遗留模式 syscall 是内核要处理的噩梦; 32 位 Linux 内核甚至不启用它。 64 位 Linux 内核确实允许来自支持该功能的 AMD CPU 上的 32 位用户-space(兼容模式)的系统调用。 (一些链接到 中内核 asm 入口点的相关评论。)

注意 AMD CPUs 在兼容模式下不支持 sysenter,只支持传统模式,所以在 64 位内核下显然你必须在 32 中使用 syscall -bit user-space 如果你想避免 AMD 上的慢 int 0x80


AMD 设计了 ​​AMD64(成为 x86-64),并为 syscall 如何工作定义了一个新的(相当好的)行为 在 64 位模式下 这是不同于它在 32 位模式下的工作方式。 (例如,在 64 位用户 space 中,它会将旧的 RFLAGS 保存到 R11 中,这在传统模式中不存在,因此不可能是它在那里所做的。)

英特尔采用 64 位 syscall 作为与 AMD 兼容的方式实现其 x86-64 版本的一部分。(模数一些实现错误,例如,如果您尝试 sysret 使用非规范的 RCX 用户-space return 地址会发生什么;在 Intel 上,故障是在特权级别 = ring 0 时发生的,但 RSP 仍然是已恢复的用户-space 堆栈 => 另一个线程可以接管内核。因此内核只能在已知 RCX 安全的情况下安全地使用它。)

即AMD的系统调用指令赢得了x86-64,因为他们设计了AMD64,而Intel则押注于IA-64(Itanium);他们的 syscall 指令成为任何人在 x86-64 上使用的唯一标准,因为没有理由使用其他任何东西。 syscall 高效并满足内核开发人员的需求。

因此不需要调度来选择适用于当前 CPU 的指令。


https://reverseengineering.stackexchange.com/questions/16454/struggling-between-syscall-or-sysenter-windows 解释更多细节。