【问题标题】:How i can access a variable data using a variable value in adress like [ var_+[second_byte] ]?我如何使用 [ var_+[second_byte] ] 之类的地址中的变量值访问变量数据?
【发布时间】:2019-11-13 18:57:13
【问题描述】:

我得到了这个代码:

BITS 16

data:

    bytemap: db 0x0, 0x1, 0x4;
    pixel_x: db 2; to return the 0x4 value

main:

    ; code...

    mov al, [bytemap+[pixel_x]]; i need that byte in al register

    ; more code...

    jmp main;

但 nasm 返回“表达式语法错误”,我尝试使用 mov bl, [pixel_x]; mov al, [bytemap+bl],但不起作用,如何正确处理? (如果存在的话)...

【问题讨论】:

标签: assembly x86 nasm addressing-mode


【解决方案1】:

您需要在寻址模式中使用指针宽度寄存器。 x86 没有内存间接寻址模式,只有寄存器间接寻址模式。 Referencing the contents of a memory location. (x86 addressing modes)。您可以在一条指令中执行的操作的限制来自机器代码可以表示的内容。汇编器不是编译器。每行都必须作为一条机器指令工作。

理想情况下,将pixel_x 保存在寄存器而不是内存中;这就是寄存器的用途。

假设是 32 位代码,

   movzx eax, byte [pixel_x]
   movzx eax, byte [bytemap + eax]     ; AL = EAX = bytemap[pixel_x]

如果您想在寄存器中使用 pixel_x 值以供以后使用,当然可以使用不同的 reg,例如 EBX。

或者在这种情况下,imul eax,eax 因为数组条目只是索引平方;你不需要查找表。

在 64 位代码中,您将使用 default rel,因此 movzx eax, byte [pixel_x] 使用 RIP 相对寻址模式。您可能需要将bytemap 的地址放入代码where static addresses aren't guaranteed to fit in a 32-bit sign-extended displacement 中的单独寄存器中。


在 16 位代码中(可以假设 386 兼容),您需要处理 16 位寻址模式的限制:只有 BX、BP、SI 和 DI 可以是基址或索引寄存器。 NASM x86 16-bit addressing modes

   movzx bx, byte [pixel_x]
   movzx ax, byte [bytemap + bx]      ; AL = AX = bytemap[pixel_x]

如果(不太可能)您的代码需要在 8086 到 286 上运行,则需要模拟 movzx。

在 16 位模式的现代 x86 上,使用 EBX 和 EAX 作为movzx 的目标可能有助于提高性能,但会增加代码大小。如果您正在编写 16 位代码,您可能不关心速度,只关心代码大小。如果性能很重要,您可以切换到保护模式或长模式。


movzx 是加载单个字节的最佳/最有效方式,零扩展至完整寄存器以避免部分寄存器性能问题,如错误依赖。仅当您真正想要合并到 EAX/RAX 的低字节时才使用mov al, [mem]

对于字节存储,你仍然只是读取部分寄存器,如mov [mem], al

阅读部分 regs 很好,只是当您可以使用 movzx 代替时,通常避免编写它们。 add al, [mem] 之类的东西在大多数 CPU 上也很有效。 Why doesn't GCC use partial registers?

一般来说,使用部分寄存器并不是灾难,只要使用movzxmovsx 而不是mov,就可以轻松避免它。

【讨论】:

  • 但是我如何才能将eax 值作为一个字节?因为当我尝试将eax 移动到 1 字节内存或像al 这样的寄存器时,我不能使用mov byte [my_byte], eaxmov al, eax,因为我需要al 中的那个字节才能绘制内存地址。但是感谢答案:)
  • @PatrickSant:对于您仍在使用mov [mem], al 的商店。读取部分寄存器很好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-03
  • 1970-01-01
  • 2012-11-04
  • 2023-02-04
  • 1970-01-01
相关资源
最近更新 更多