【问题标题】:NASM produces unexpected extra operand size prefix [duplicate]NASM 产生意外的额外操作数大小前缀 [重复]
【发布时间】:2022-11-01 13:48:32
【问题描述】:

我在 Linux amd64 上运行 NASM 时遇到问题。

在单个指令 mov eax, 0x12345678 上运行 nasm 会产生 6 个字节:

00000000 <.data>:
   0:   66 b8 78 56             mov    $0x5678,%ax
   4:   34 12                   xor    $0x12,%al

但是,在 AT&T 格式 mov $0x12345678, %eax 的同一条指令上使用 as 会产生 5 个字节的正确结果:

0000000000000000 <.text>:
   0:   b8 78 56 34 12          mov    $0x12345678,%eax

NASM 我缺少什么?

【问题讨论】:

标签: assembly x86 nasm machine-code instruction-encoding


【解决方案1】:

NASM 认为您正在组装 16 位代码,看到 32 位指令,并在其上添加大小覆盖前缀。然后反汇编程序认为您正在反汇编 32 位代码,被大小覆盖前缀弄糊涂了,并假设它是 2 条指令。

GAS 认为您正在组装 32 位代码,因此它不会生成大小覆盖前缀。

您可以通过弄清楚它为什么认为您正在组装 16 位代码来修复 NASM。这是“平面二进制”输出文件格式的默认设置,如果是这种情况,您可以通过在 32 位指令之前的某处放置 bits 32 指令来修复它。

或者,也许您正在尝试汇编 16 位代码并且 GAS 是错误的。在这种情况下,您可能需要在 16 位代码之前的某处使用 .code16 指令。

请注意,大小覆盖前缀的工作方式类似于切换 - 如果默认大小为 16 位,则前缀使指令为 32 位;如果默认大小为 32 位,则相同的前缀使指令为 16 位。

【讨论】:

  • 在 AMD64 Linux 上,如果您在没有选项的情况下运行 GAS,GAS 知道它正在生成 x86-64 .o,因此它实际上是针对 64 位模式进行组装的。 (没有前缀的机器码中的默认操作数大小也是32位的,除了一些操作码,所以总体来说是正确的。)
猜你喜欢
  • 1970-01-01
  • 2018-10-04
  • 1970-01-01
  • 1970-01-01
  • 2020-10-27
  • 2021-11-07
  • 2013-09-23
  • 2016-04-05
  • 1970-01-01
相关资源
最近更新 更多