实模式和取消引用中的 32 位寄存器

32-bit registers in real mode and dereferencing

我正在为 MBR(实模式)编写一些程序集。我知道在实模式下你不能使用 32 位寄存器,只能使用 16 位寄存器。

我写了这段依赖于 print_char 函数的代码。

    mov ecx, MSG
write:
    mov al, [ecx]
    cmp al, 0x0
    je end_print
    call print_char
    inc cx
    jmp write
end_print:
    ret
MSG: db 'Hi!', 0xd, 0xa, 0x0

此代码无法编译,原因如下:

error: invalid effective address

我用

nasm -f bin -o out src.s

当我将寄存器名称更改为 ecx 时,代码开始编译,令人惊讶的是,它可以运行。

为什么我的代码使用 32 位寄存器可以在实模式下工作,为什么使用 16 位寄存器不能?

x86 ISA 支持多种寻址模式。有两组寻址模式,一组用于16位模式,一组用于32位模式。

在 32 位模式下,您可以对任何寄存器使用变址寻址和三部分 SIB 寻址。

在16位模式下,只有以下寻址方式存在(各有可选位移):

BX + disp
BX + SI + disp
BX + DI + disp
BP + disp
BP + SI + disp
BP + DI + disp
SI + disp
DI + disp
disp

请注意 cx 不能用作索引寄存器。

解决这个问题的方法是在 16 位模式下使用 32 位寻址模式。这是通过像您一样将 ecx 指定为索引寄存器来完成的。