试图缩小我的问题范围,以便我能够克服这个障碍。This https://stackoverflow.com/questions/28664856/how-to-interpret-x86-opcode-map?noredirect=1#comment116568309_28664856对我帮助不大。
我正在运行 NASM 来查看汇编的输出以十六进制表示。
test:
@nasm -f macho64 test.asm
@objdump -x86-asm-syntax=intel --full-leading-addr -d test.o
.PHONY: test
在那里我有一些东西,其中之一是:
add cl, 2
其输出为:
80 c1 02
看着英特尔手册 https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf,我转到 ADD 部分,它显示了以下内容:
80 /0 ib
看起来足够接近了,80
在那里,并且ib
是我的号码2
即时价值。但如何计算这个c1
来自/0
?
文档说:
/digit— 0 到 7 之间的数字表示指令的 ModR/M 字节仅使用 r/m(寄存器或内存)操作数。这reg字段包含提供指令操作码扩展的数字。
我的问题是:
- 为什么汇编器决定在这里放置 ModR/M 字节?
- “仅使用 r/m(寄存器或内存)操作数”是什么意思?什么操作数,是说它认识到有一个寄存器
cl
并立即2
,所以它选择cl
因为它是一个寄存器?
- “reg 字段包含为指令的操作码提供扩展的数字。”唔?这是什么意思?我能从中收集到的就是,
/0
意思是它是第0个寄存器?但这不起作用,似乎是错误的。
- 表2-1有值
c1
其中,与cl
在“有效地址”标题下注册。虽然不知道这意味着什么。相应的 R/M 位就在那里001
,它所在的列是0
。尽管这些对我来说还没有多大意义。
我如何说服自己这c1
字节是否正确?我如何读取各个表中的所有符号,我如何自己通过查看汇编和英特尔表来推断出它?
- 因为
Op/En
为了80 /0 ib
says MI
这表示 Operand1 位于MODRM:r/m
.
- 这意味着它仅使用 modr/m 的“r/m”部分,而不使用“reg”部分。
- 表示“reg”部分包含一个常量
0
作为操作码扩展。
- 你看一下 modr/m 表 2-2,它有一个标题行,上面写着“/digit (Opcode)”。所以你选择
0
列因为/0
。然后选择ECX/CX/CL/MM1/XMM1
行瞧,你得到了你的C1
value.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)