Assembly 如何通过操作码确定是否需要ModR/M?

Assembly 如何通过操作码确定是否需要ModR/M?,assembly,x86,opcode,machine-code,instruction-set,Assembly,X86,Opcode,Machine Code,Instruction Set,我正在阅读ia-32指令格式,发现如果需要,ModR/M是一个字节,但如何确定是否需要,有人说这是由操作码决定的,但如何确定?我想知道细节,是否有一些有用的权威文件来解释细节 英特尔第二卷手册详细介绍了每种指令形式的操作数编码。e、 g.只取已知指令的8位操作数大小版本,该指令有2个reg、rm形式;rm,直接形式;还有一个no ModRM 2字节,是add al的缩写,imm8 下面的指令操作数编码表详细说明了上面Op/En操作数编码列中的I/MI/MR/RM代码的含义: Op/En |

我正在阅读ia-32指令格式,发现如果需要,ModR/M是一个字节,但如何确定是否需要,有人说这是由操作码决定的,但如何确定?我想知道细节,是否有一些有用的权威文件来解释细节

英特尔第二卷手册详细介绍了每种指令形式的操作数编码。e、 g.只取已知指令的8位操作数大小版本,该指令有2个reg、rm形式;rm,直接形式;还有一个no ModRM 2字节,是add al的缩写,imm8

下面的指令操作数编码表详细说明了上面Op/En操作数编码列中的I/MI/MR/RM代码的含义:

Op/En   | Operand 1        | Operand 2     | Operand 3  Operand 4
RM      | ModRM:reg (r, w) | ModRM:r/m (r) |  NA        NA
MR      | ModRM:r/m (r, w) | ModRM:reg (r) |  NA        NA
MI      | ModRM:r/m (r, w) | imm8/16/32    |  NA        NA
I       | AL/AX/EAX/RAX    | imm8/16/32    |  NA        NA
注意,I操作数形式没有提到ModRM,因此没有ModRM。但是我有一个。使用操作码表中80/0中的/0填充/r字段:以83/0添加r/m64、imm8为例

请注意,RM和MR的区别仅在于可以作为内存的r/m操作数是目标还是源

大多数x86 ALU指令都有四个reg、r/m操作码,分别对应于由66个操作数大小前缀确定的8位和非8位大小的MR和RM,以在16位和32位之间翻转,或REX.W表示64位,或在除16位以外的模式下,默认操作数大小32为无

加上标准的立即形式:

立即共享一个操作码字节的r/m8位 r/m 16/32/64位,带8位符号扩展立即共享操作码字节,通过/digit重载 r/m 16/32/64位,带16/32/sign\u extended\u 32位立即共享通过/digit重载的操作码字节 AL无modrm,具有8位立即全操作码字节 AX/EAX/RAX无modrm,imm16/imm32/sign\u将imm32整个操作码字节扩展到自身 每个助记符都有很多操作码,这就是为什么8086没有空间按照与通常指令相同的模式进行更多操作

另请参见比英特尔手册更简洁的内容。还请注意,您可以通过使用诸如NASM或GAS之类的汇编器组装某些东西并查看机器代码来检查您的理解。或者只看一下现有程序的反汇编,比如objdump-drwC-Mintel/bin/ls | less


有些反汇编程序甚至将每条指令的机器代码中的字节分组在一起,例如,将4字节的立即数作为一个组与操作码和modrm分开。是这样的。

英特尔第二卷手册详细介绍了每种指令形式的操作数编码。e、 g.只取已知指令的8位操作数大小版本,该指令有2个reg、rm形式;rm,直接形式;还有一个no ModRM 2字节,是add al的缩写,imm8

下面的指令操作数编码表详细说明了上面Op/En操作数编码列中的I/MI/MR/RM代码的含义:

Op/En   | Operand 1        | Operand 2     | Operand 3  Operand 4
RM      | ModRM:reg (r, w) | ModRM:r/m (r) |  NA        NA
MR      | ModRM:r/m (r, w) | ModRM:reg (r) |  NA        NA
MI      | ModRM:r/m (r, w) | imm8/16/32    |  NA        NA
I       | AL/AX/EAX/RAX    | imm8/16/32    |  NA        NA
注意,I操作数形式没有提到ModRM,因此没有ModRM。但是我有一个。使用操作码表中80/0中的/0填充/r字段:以83/0添加r/m64、imm8为例

请注意,RM和MR的区别仅在于可以作为内存的r/m操作数是目标还是源

大多数x86 ALU指令都有四个reg、r/m操作码,分别对应于由66个操作数大小前缀确定的8位和非8位大小的MR和RM,以在16位和32位之间翻转,或REX.W表示64位,或在除16位以外的模式下,默认操作数大小32为无

加上标准的立即形式:

立即共享一个操作码字节的r/m8位 r/m 16/32/64位,带8位符号扩展立即共享操作码字节,通过/digit重载 r/m 16/32/64位,带16/32/sign\u extended\u 32位立即共享通过/digit重载的操作码字节 AL无modrm,具有8位立即全操作码字节 AX/EAX/RAX无modrm,imm16/imm32/sign\u将imm32整个操作码字节扩展到自身 每个助记符都有很多操作码,这就是为什么8086没有空间按照与通常指令相同的模式进行更多操作

另请参见比英特尔手册更简洁的内容。还请注意,您可以通过使用诸如NASM或GAS之类的汇编器组装某些东西并查看机器代码来检查您的理解。或者只看一下现有程序的反汇编,比如objdump-drwC-Mintel/bin/ls | less


有些反汇编程序甚至将每条指令的机器代码中的字节分组在一起,例如,将4字节的立即数作为一个组与操作码和modrm分开。是这样的。

仍然无法理解80/0IB中的/0,请您进一步解释一下好吗?请看我关于另一个问题的回答:。@PeterCordes Op/En中的R | M | I代表寄存器/内存/立即数吗?那么,为什么最后一个Op/En有I而没有RI?R=reg,M=R/M,I=immediate。I表单没有ModRM字节;AL/AX/EAX/RAX操作系统
rand是隐式的,由操作码暗示,而不是在任何地方编码。因此,在操作数编码中没有提到R。读了这篇文章后,我仍然不明白。仍然不明白80/0 ib中的/0,请您进一步解释一下,好吗?请看我关于另一个问题的答案:。@PeterCordes Op/En中的R | M | I代表寄存器/内存/立即数吗?那么,为什么最后一个Op/En有I而没有RI?R=reg,M=R/M,I=immediate。I表单没有ModRM字节;AL/AX/EAX/RAX操作数是隐式的,由未编码的操作码隐含。所以在操作数编码中没有提到R,读了这篇文章后我还是不明白。