在英特尔的开发人员手册中,可以从ModR / M字节中扣除哪个操作数“拥有”REG部分,以及哪个操作数具有标准操作码映射中的Mod + RM部分,可选择使用方向位?方向位是否符合具有两个操作数的所有操作(方向可能不明确)?
我从单字节操作码映射的顶部开始。我们在这里:
0 1 2 3 4 5 6 7
+--------|--------|--------|--------|--------|---------|---------|---------|
0 | ADD | PUSH | POP |
| Eb, Gb | Ev, Gv | Gb, Eb | Gv, Ev | AL, Ib | rAX, Iz | ES(i64) | ES(i64) |
+--------|--------|--------|--------|--------|---------|---------|---------|
1 | ADC
…
我将ADD
视为操作码00h
和02h
。
字母说明:
Addressing methods:
…
E A ModR/M byte follows the opcode and specifies the operand. The
operand is either a general-purpose register or a memory address. If
it is a memory address, the address is computed from a segment
register and any of the following values: a base register, an index
register, a scaling factor, a displacement.
G The reg field of the ModR/M byte selects a general register.
Example: AX (000)
…
-------------------------------------------------------------------------
Operand types:
…
b Byte, regardless of operand-size attribute.
v Word, doubleword or quadword (in 64-bit mode), depending on
operand-size attribute.
…
如上所述,我正在查看ADD
操作码00h
和02h
。此外,我只看32位(现在)。操作的描述表是:
Opcode Instruction Op/en Description
00 /r ADD r/m8,r8 MR Add r8 to r/m8.
02 /r ADD r8,r/m8 RM Add r/m8 to r8.
00 05 e25a4600 add [0x465ae2], al
00 0d e25a4600 add [0x465ae2], cl
00 06 add [esi], al ; Eb, Gb
02 06 add al, [esi] ; Gb, Eb
00 c8 add al, cl ; Eb, Gb
02 c8 add cl, al ; Gb, Eb
00 05 e0514600 add [0x4651e0], al
02 05 e0514600 add al, [0x4651e0]
7 6 5 4 3 2 1 0 Bit
+------------+------------------+------------------+
| MOD | REG/Opcode | R/M |
+------------+------------------+------------------+
来自二进制测试用例的操作码和ModR / M:
Opcode Mod REG/opc R/M
0000 0000 00 000 101 add [0xNNNNNN], al
0000 0000 00 001 101 add [0xNNNNNN], cl
0000 0000 00 000 110 add [esi], al
0000 0010 00 000 110 add al, [esi]
0000 0000 11 001 000 add al, cl
0000 0010 11 001 000 add cl, al
0000 0000 00 000 101 add [0xNNNNNN], al
0000 0010 00 000 101 add al, [0xNNNNNN]
|
+-----> Direction bit?
(Ups,那个引言越来越大,TLDR?)但是,最后:
E
(第一个表)中的描述指出“操作码后面的操作数是一个ModR / M字节。操作数是通用寄存器或存储器地址。“ E
符号。
G
标志,表示“ModR / M字节的寄存器字段选择通用寄存器”。这总是如此吗?附录B 有一个简短的部分说明:
B.1.4.8方向(d)位
在许多双操作数指令中,方向位(d)表示哪个 操作数被视为源,哪个是目的地。看到 表B-11。
Table B-11. Encoding of Operation Direction (d) Bit
+---+-----------------------------+---------------------------------+
| d | Source | Destination |
+---+-----------------------------+---------------------------------+
| 0 | reg Field | ModR/M or SIB byte |
| 1 | ModR/M or SIB Byte | reg Field |
+---+-----------------------------+---------------------------------x
2。 很多在这里意味着什么?它在哪里定义哪些适用,哪些不适用?
希望这不会变得很久。
答案 0 :(得分:2)
有关Mod / RM编码,请参阅this表。
首先,并不总是有方向位。据我所知,仅在ALU ops *中。方向位表示E部分或G部分中的哪一个是源,哪个是目的地。
E操作数是寄存器操作数还是内存操作数的定义是Mod / RM字节的MOD部分是11(寄存器)还是不是(存储器),因为您可能从我链接的表中看到至。 R字段并不总是对通用寄存器进行编码,它可以编码其他类型的寄存器,甚至可以扩展操作码(两者也都由该表显示),但G字段总是编码GPR(它指的是R字段)当然是Mod / RM字节,但是当它被称为G时,你知道它必须是GPR,否则它可能是其他东西,它取决于它是什么操作数的指令。)
新指令都没有真正的方向位。除了仅写入且不读取/修改/写入的指令外,它们中的大多数都无法写入内存。例如,有movaps r, r/m
和movaps r/m, r
,以及movdqa r, r/m
和movdqa r/m, r
,它们可以被解释为具有方向位,但对于movaps
,它位0和movdqa
它的位数为4.您可以说只有两种不同的编码。
*具体而言,由00aa a0ds
描述的组,其中aaa
是操作(add,adc,和xor,或sbb,sub,cmp,从0到7的顺序), d
是方向位,s
表示大小(0表示字节操作,1表示其他所有内容,由当前模式和前缀区分)