首页 > 解决方案 > Intel CPU 上的 SYSENTER

问题描述

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

标签: winapiassemblyx86x86-64system-calls

解决方案


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

32 位代码使用任何 CPU 支持的比int.


您关于仅支持 AMD 的信息仅在 32 位用户空间模式(旧版和兼容模式)下syscall才是正确的。

英特尔sysenter成为 32 位用户空间的首选;英特尔赢得了这场争夺主导地位的斗争。此外,显然 AMD 的传统模式syscall对内核来说是一场噩梦。32 位 Linux 内核甚至不启用它。64 位 Linux 内核确实允许在支持该功能的 AMD CPU 上从 32 位用户空间(兼容模式)进行系统调用。(此答案中有关内核 asm 入口点的相关评论的一些链接。)

请注意,AMD CPU 不支持sysenter兼容模式,仅支持传统模式,因此在 64 位内核下,如果您想避免AMDsyscall速度变慢,显然您必须在 32 位用户空间中使用。int 0x80


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

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

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

因此,无需调度以选择在当前 CPU 上工作的指令。


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


推荐阅读