当提到MODR/M字节时,8086文档站点似乎有点模糊,很难理解它是什么和做什么。
MODR/M字节中使用的所有位元是什么,可能的选项是什么?
我找到的一些文档:02.htm
The ModR/M byte contains three fields of information:
The mod field, which occupies the two most significant bits of the byte, combines with the r/m field to form 32 possible values: eight registers and 24 indexing modes
The reg field, which occupies the next three bits following the mod field, specifies either a register number or three more bits of opcode information. The meaning of the reg field is determined by the first (opcode) byte of the instruction.
The r/m field, which occupies the three least significant bits of the byte, can specify a register as the location of an operand, or can form part of the addressing-mode encoding in combination with the field as described above什么是索引模式?注册号码是多少?寄存器是如何表示的?等。
发布于 2022-06-11 06:46:58
英特尔自己的PDF手册详细记录了这一点;请参阅SDM第2卷,特别是每条指令条目之前的介绍章节。
在字节数这样的网站上也有详细的描述(它涵盖了16位ModRM,所以它不仅仅是在谈论x86-64长模式)。现代x86使用与8086相同的指令编码(16位实模式);向后压缩是x86的全部要点,也是为什么它如此令人讨厌。
当然,您可以找到实际8086手册本身的PDF副本,以防忽略仅与其他模式相关的内容更有帮助。
从第23页起的8086引物涵盖操作数的指令编码。它写成了一本书,而不仅仅是一本技术手册。它可以在Stephen的网站(https://stevemorse.org/8086/)上免费获得,他是英特尔公司的设计师。
但是,它可能有助于描述ModRM用途的基本概述,因此您可以知道在这些文档中查找什么。
ModR/M的目的和基础
大多数(但不是所有) x86指令都有一个ModRM字节。它可以对两个操作数进行编码,其中一个是内存,或者是两个寄存器。例如add cx, ax,或add cx, [bx+si]。
操作码本身确定r/m和r操作数中的哪个是源和/或目的,或者/r字段是否充当额外的操作码位。(例如,对于轮班,这就是它们不能复制和移位,或者使用CL以外的计数寄存器的原因。) add [bx+si], cx具有与add cx, [bx+si]相同的ModRM字节,但具有不同的操作码。
只有寄存器的操作数是3位/r字段的代码.3位可以编码任何x86的8个通用寄存器.这是一个“寄存器号”,就像在任何带有2^n寄存器的普通ISA中一样,每个寄存器操作数的指令代码中都有n个位组。
r/m操作数也可以是寄存器,但2位“模式”字段决定3位r/m字段是寄存器号(mod=0b11)还是内存寻址模式。(加上8或16位位移量,所以对disp0 0/8/16的编码会耗尽模式字段的其他3种编码。)
字节数显示16位地址大小的字段和解释,包括寄存器号.
因此,只有3位来指定寄存器或寄存器组合的内存地址。386为SIB字节添加了转义代码,允许像[eax + ecx*4]这样的寻址模式的全部选择,但是8086 (以及任何CPU上的16位地址大小)必须是[BX|BP] + [SI|DI] + disp0/8/16的一些子集。
见8086:[bx]作品中通用寄存器之间的差异,[cx]不是吗? / 为什么x86 16位寻址模式没有一个缩放因子,而32位版本有吗?
例如组装foo.asm,然后组装ndisasm -b16 foo,或者要求NASM自己使用nasm -l/dev/stdout foo.asm进行列表。然后编辑以简化输出字段。
00 00 add [bx+si],al ; opcode=0x00 (add byte, mem dst) mod=00 r=000 r/m=000
01 C0 add ax, ax ; add r/m, r mod=11 (register) r=000 (AX) r/m=0 (AX)
01 08 add [bx+si], cx ; add r/m, r
03 08 add cx, [bx+si] ; mod=0, r=001 (CX) r/m=000 ([bx+si])
03 0F add cx, [bx] ; mod=00 r=001 (CX) r/m=111 ([BX])
03 4F 04 add cx, [bx + 4] ; mod=01 r=001 (CX) r/m=111 disp8=4
01 F2 add dx, si ; mod=11 r=110 (SI) r/m=010 (DX)若要创建更多示例,请使用汇编程序自己创建机器代码。
另请参阅
/r字段ModRM被用作额外的操作码位时,如FF /2调用r/m16调用接近,绝对间接。https://stackoverflow.com/questions/72581111
复制相似问题