2017-04-02 111 views
-2

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

我写了这个代码,它依赖于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位寄存器不是?

+2

您可以在32位cpu上使用32位寄存器,实模式还是不使用。但是如果你使用16位寻址,你必须使用有效的模式,'[cx]'不是一个。 – Jester

+0

为什么降价? – marmistrz

+0

我没有倒下,但我的猜测是他们觉得“它没有显示任何研究成果”。您可以自己查看intel手册中的寻址模式,特别是_“地址大小覆盖前缀(67H)允许程序在16位和32位寻址之间切换。任何一种大小都可以是默认值;前缀选择非默认大小。“_ – Jester

回答

1

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指定为索引寄存器来完成的。

+0

为什么我可以在16位模式下使用32位寻址?如果处理器对其本身施加了额外的16位约束,则不应该允许它。 – marmistrz

+1

没有理由限制这一点。它向后兼容,只是给你更多的选择。请注意,您可以同样在32位模式下使用16位寻址,在64位模式下使用32位寻址(但只有最后一个通常有用)。 – Jester

+1

@marmistrz基本上,32位模式的设计使得16位程序可以根据需要使用32位指令。这是通过两个前缀66和67完成的,它们切换数据并寻址到32位模式。在32位模式下,这些前缀的含义简单相反。 – fuz

相关问题