【问题标题】:32-bit registers in real mode and dereferencing实模式下的 32 位寄存器和取消引用
【发布时间】:2017-04-02 11:27:14
【问题描述】:

我正在为 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 位寄存器不能?

【问题讨论】:

  • 您可以在 32 位 cpu 上使用 32 位寄存器,无论是否为实模式。但是如果使用 16 位寻址,则必须使用有效模式,[cx] 不是一种。
  • 为什么要投反对票??
  • 我没有投反对票,但我猜他们觉得“它没有显示出任何研究努力”。您可以自己在 intel 手册中查找寻址模式,特别是 “地址大小覆盖前缀 (67H) 允许程序在 16 位和 32 位寻址之间切换。任何一个大小都可以是默认值;前缀选择非默认大小。"
  • 我真的不知道要搜索什么。搜索无效的有效地址没有产生任何有用的信息。

标签: assembly real-mode


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

【讨论】:

  • 为什么在 16 位模式下可以使用 32 位寻址?如果处理器对其自身施加额外的 16 位约束,则不应允许。
  • 没有理由限制这一点。它是向后兼容的,只是为您提供了更多选择。请注意,您可以类似地在 32 位模式下使用 16 位寻址,在 64 位模式下使用 32 位寻址(但通常只有最后一个有用)。
  • @marmistrz 基本上,32 位模式的设计使得 16 位程序可以根据需要使用 32 位指令。这是通过两个前缀 66 和 67 完成的,它们将数据和寻址切换到 32 位模式。在 32 位模式下,这些前缀的含义被简单地颠倒了。
猜你喜欢
  • 2014-11-17
  • 2011-10-18
  • 2011-10-26
  • 2014-11-18
  • 1970-01-01
  • 2015-04-21
  • 2012-04-11
  • 2022-07-18
  • 2020-11-21
相关资源
最近更新 更多