assembly 为什么NASM / ndisasm将相对jmp/call指令的操作数视为绝对操作数?

k4emjkb1  于 2022-12-29  发布在  其他
关注(0)|答案(1)|浏览(119)

根据“x86指令集参考”,EB cb操作码对应于JMP rel8助记符,而助记符又对应于“短跳转,相对,相对于下一条指令的位移”。由此,可以得出结论(至少我会)JMP的操作数表示操作码和助记符相对于IP的偏移量。下面的代码片段证明了其他情况:

bits 16
nop
nop
nop
nop
nop
jmp label
label:
   nop

使用nasm -f bin -o test.bin test.asm组装,然后使用ndisasm -b 16 test.bin拆卸,它会产生以下输出:

00000000  90                nop
00000001  90                nop
00000002  90                nop
00000003  90                nop
00000004  90                nop
00000005  EB00              jmp short 0x7
00000007  90                nop

EB00操作码的第二个字节是0,这是正确的,并且是预期的,因为跳转目标是下一条指令(因此偏移量为0),但对应的jmp助记符的操作数为7,这显然是一个绝对地址。我可以在上面代码中的JMP指令前添加任意多个NOP(或任何其它指令),其效果将是使得JMP指令的操作码将保持相同,但是其对应助记符的操作数将相应地增加以调整到跳转目标的绝对地址,而不是相对地址。预期的,有意的,所有汇编器都通用的,不仅仅是NASM?相对CALL指令的行为是一样的。这是它应该的方式吗?

whhtz7ly

whhtz7ly1#

为什么NASM/ndisasm将相对jmp/call指令的操作数视为绝对操作数?
机器代码对CPU来说很好,但对人类来说很不方便。在机器代码中,jmp/call指令的操作数是相对的。
汇编语言更适合人类(但对CPU来说不方便),在汇编语言中,jmp/call指令的操作数是绝对的,因为这对人类更好。
工具(汇编器,链接器)将"对人类更好"翻译成"对CPU更好",包括将绝对地址转换成相对偏移量。
更多的工具(反汇编器)则相反,将"对CPU更好"翻译成"对人类更好",包括将相对偏移量转换成绝对偏移量。

相关问题