Assembly 实模式32位寄存器

Assembly 实模式32位寄存器,assembly,x86,32-bit,16-bit,real-mode,Assembly,X86,32 Bit,16 Bit,Real Mode,我正在编写一些实模式代码,并使用32位寄存器来实现(使用0x66前缀) 我一直在看英特尔的手册,但找不到我要找的信息。 见:(我浏览了第一卷第1-7章,以及第二卷的具体说明) 英特尔是否保证以下代码在实模式代码中的特定行为?它与保护模式代码相同吗 mov eax, <some constant> mov ebx, <some constant> add ax, bx ; Are the top bits of ax zero'd, sign extended or lef

我正在编写一些实模式代码,并使用32位寄存器来实现(使用0x66前缀)

我一直在看英特尔的手册,但找不到我要找的信息。 见:(我浏览了第一卷第1-7章,以及第二卷的具体说明)

英特尔是否保证以下代码在实模式代码中的特定行为?它与保护模式代码相同吗

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?
mov-eax,
mov-ebx,
添加ax、bx;ax zero'd的顶部位是扩展的还是左侧的?
mov-ax;这会保持前16位不变吗?
; 据我所知,前16位是不变的,但这是在哪里记录的?
注意:我并不是在讨论具体的实现是如何运作的(即检查它的代码——除非每个实现都是一样的),而只是英特尔已经记录了这种行为

相关的:

这是如何不同的:这个问题特别与实际模式操作有关,以及来自链接问题的观察结果在实际模式下是否有效


有人能帮我找到在哪里可以找到实数模式代码的文档吗?

前16位的内容保持不变。零扩展()和符号扩展()有单独的说明。我确信在某些地方有文档记载ax引用eax寄存器的较低16位,在这种情况下,零扩展将是“非默认”行为,如x86_64。x86_64文档中也明确说明了这种行为。

以下第3.4.1节或多或少地记录了16位和8位备用寄存器名仅访问其各自子部分的事实:

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?
如图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位发生了什么。

“我确信它在某个地方被记录了下来。”--这就是问题所在--在哪里?@James我以为你在问零/符号扩展发生或不发生在哪里有记录,我是说它可能根本没有记录,因为没有理由认为它应该发生。但是ax是eax的一部分这一事实在“某处”被记录了下来:)我不需要担心我的执行环境,因为我没有执行环境。谢谢,当我阅读本章时,我实际上完全跳过了64位模式注释,因为我没料到会在那里详细说明行为。严格来说,64位部分不适用于实际模式。在实模式下,64位寄存器的上32位发生的情况未定义。而且,除非您正在编写自己的BIOS固件或等效固件,否则您可能仍然需要担心其他代码会破坏32位寄存器。