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