winapi - Intel CPU 上的 SYSENTER
问题描述
因此,AFAIK syscall指令相当于 AMD 的sysenter。所以理论上应该只在 AMD 芯片上找到一个系统调用指令,对吗?好吧,显然情况并非如此,因为我弄乱了 ntdll.dll 和 ntdll.dll(WOW64 版本),我发现常规版本使用syscall而来自 WOW64 的 ntdll.dll 使用sysenter。这是为什么?
解决方案
所有 x86-64 CPU 都支持syscall
64 位模式;这是进行 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 上工作的指令。
推荐阅读
- javascript - 过滤出特定多个键的数组
- python - 屏幕搜索和 pyautogui 图像问题(“NoneType”对象没有属性“形状”)
- python - 有没有办法在 Seaborn 中使用预先计算的距离和颜色条/条码表示?
- firebase - Flutter Android 构建因 firebase 依赖项而失败(找不到 com.google.firebase:firebase-common)
- spring-boot - 春季验证:@Pattern 的 ConstraintViolationException 由于密码编码
- javascript - 测试库 - 测试依赖于 CSS 的逻辑
- java - 在 Spring Boot Cucumber 测试中动态更改属性文件的值
- python - Python Selenium - 我该如何处理这个基本代码?
- python - Autokeras ValueError:期望 StructuredDataInput 的数据具有形状
- c - 关于 C 中的信号