为什么 `add cx, 1234` 在 NASM 16 位模式下使用 objdump 产生 <unknown>?

Why does `add cx, 1234` in NASM 16 bit mode produce <unknown> with objdump?

我有这个:

bits 16
global start
section .text
start:
  add cx, 1234

使用此 Makefile:

test:
    @nasm -f macho64 test.asm
    @objdump -x86-asm-syntax=intel --full-leading-addr -d test.o
.PHONY: test

它打印:

% make

test.o: file format Mach-O 64-bit x86-64


Disassembly of section __TEXT,__text:

0000000000000000 start:
      0: 81 c1                          <unknown>
      2: d2 04                          <unknown>

为什么会生成<unknown>而不显示这里的指令?我做错什么了吗?仍在学习机器代码的基础知识,如果很明显,请见谅。

它似乎在 32 位模式下工作正常:

bits 32
global start
section .text
start:
  add cx, 1234

输出:

% make

test.o: file format Mach-O 64-bit x86-64


Disassembly of section __TEXT,__text:

0000000000000000 start:
      0: 66 81 c1 d2 04                 add cx, 1234

opcode 81 在 64 位模式下需要 5 个字节(modrm + imm32),但是您的 .text 段在此之前结束,因此反汇编器放弃了。如果你用更多的字节填充文本部分(比如 times 10 db 0),你会得到一些东西。

您使用 bits 16 将非 64 位机器代码放入 64 位目标文件中,因此您当然应该预料到通常会出现错误。

16 位模式的默认操作数大小 (16) 与 32 位和 64 位模式 (32) 不同,因此 66 操作数大小前缀使事情相反。在 32 位或 64 位模式下需要 66 前缀的指令(如 add cx, 1234),要求它在 16 位模式下不存在。 (如您上一个问题 中所述)