试图了解 cmp 如何与 NASM 一起使用,在this page我找到了以下内容:
CMP r/m32,reg32 ; o32 39 /r [386]
还有更多这样的。但是,我无法理解这条线的含义。
我认为[386]指的是处理器/架构。有人可以解释一下ASM声明的含义吗?
答案 0 :(得分:1)
r/m32
和reg32
是操作数规范。第一个是32位寄存器或内存操作数,第二个是32位寄存器。您链接到的该页面的B.1 Key to operand specifications
部分解释了这一点:
寄存器:reg8表示一个8位通用寄存器,reg16表示一个16位通用寄存器, reg32表示一个32位通用寄存器。 fpureg表示八个FPU堆栈寄存器之一, mmxreg表示8个64位MMX寄存器中的一个,segreg表示段寄存器。此外,可以明确指定一些寄存器(例如AL,DX或ECX)。
内存引用: mem表示通用内存引用;当操作数需要特定大小时,使用mem8,mem16,mem32,mem64和mem80。同样,在某些情况下需要说明符:DEC [地址]不明确并且将被NASM拒绝。您必须指定DEC BYTE [地址],DEC WORD [地址]或DEC DWORD [地址]。
寄存器或存储器选择:许多指令可以接受寄存器或存储器引用作为操作数。 r / m8是reg8 / mem8的简写;类似地,r / m16和r / m32。 r / m64与MMX相关,是mmxreg / mem64的简写。
同样,第B.2 Key to opcode descriptions
节显示了操作码/操作数的编码方式:
代码o16和o32表示指令的给定形式应与操作数大小为16或32位组合。换句话说,o16表示BITS 32状态中的66前缀,但生成在BITS 16状态下没有代码; o32表示BITS 16状态的66前缀,但在BITS 32中没有生成任何内容。
这解释了o32
。
十六进制数(例如3F)表示包含该数字的固定字节。
这涵盖了39
,一个固定的操作码。
代码/ r ...表示其中一个操作数是存储器地址或r / m,另一个是寄存器,并且应该使用ModR /中的备用(寄存器)字段生成有效地址M字节等于“寄存器值”#39;寄存器操作数。
详细说明了其他操作数是如何存储的,虽然它不是一个简单的过程,因为通常需要一些小的操作。我建议按照该部分给出的链接,详细说明有效地址和寄存器的编码方式。
[386]
是引入操作码/操作数集的级别。
如果确实想要理解编码,请汇编cmp
语句的几个不同变体,并查看它们生成的机器代码。然后尝试使用B.1
,B.2
,B.2.1
和B.2.5
部分将它们反汇编回源代码。
这将有助于大大加快您对其工作原理的理解。