我正在编写一些实模式代码并使用32位寄存器(使用0x66前缀)。
我一直在查看英特尔的手册,但找不到我要查找的信息。 请参阅:http://www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html(我已经浏览了第1卷第1-7章,以及第2卷的具体说明)
英特尔是否在实模式代码中保证以下代码的特定行为?它与保护模式代码相同吗?
mov eax, <some constant>
mov ebx, <some constant>
add ax, bx ; Are the top bits of ax zero'd, sign extended or left?
mov ax, <some constant> ; Does this leave top 16bits unchanged?
; From what I can tell, the top 16bits are unchanged, but where is this documented?
注意:我不会追踪特定实施的行为(即检查它的代码 - 除非每个实现始终都采取相同的行为),就在英特尔记录此行为的地方。
相关:x86_64 registers rax/eax/ax/al overwriting full register contents
这是如何不同的:这个问题特别涉及实模式操作,以及链接问题的观察是否在实模式下有效。
任何人都可以帮我找到可以找到真实模式代码的文件吗?
答案 0 :(得分:1)
Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1: Basic Architecture的第3.4.1节中或多或少地记录了16位和8位备用寄存器名称仅访问其各自子部分的事实:
如图3-5所示,通用寄存器的低16位直接映射到 找到的寄存器组 8086和Intel 286处理器可以参考名称AX,BX,CX,DX,BP,SI,DI, 和SP。每 可以通过名称引用EAX,EBX,ECX和EDX寄存器的低两个字节 AH,BH,CH和DH(高字节)和AL,BL,CL和DL(低字节)。
由于文档没有将这些备用寄存器描述为访问寄存器的指定部分以外的任何内容,因此没有理由认为它们会这样做。另请注意,3.4.1节适用于除64位模式以外的处理器的所有操作模式,因此它也包括实模式。
第3.4.1.1节介绍64位模式下发生的情况,其中您链接的帖子中描述的行为来自:
在64位模式下,操作数大小确定目标通用寄存器中的有效位数:
- 64位操作数在目标通用寄存器中生成64位结果。
- 32位操作数生成32位结果,在目标通用中零扩展为64位结果 寄存器。
- 8位和16位操作数生成8位或16位结果。高56位或48位(分别) 目标通用寄存器不会被操作修改。如果是8位或16位的结果 操作用于64位地址计算,显式地将寄存器符号扩展为完整的64位。
值得注意的是,8位和16位备用寄存器在64位模式下的工作方式与在其他模式下的工作方式相同。
最后,即使处理器在您不期望它时也不会隐含地删除寄存器的高16位,但您不一定依赖于您所处的环境。执行不执行此操作。在MS-DOS下,使用32位寄存器的高16位并不总是安全的,因为你从来不知道什么时候调用,中断服务程序或TSR会改变它们。各种调用约定和接口仅定义了保留和修改的16位寄存器,它们很少提及高16位发生的事情。
答案 1 :(得分:0)