GAS给出了以下说明以下编码:
push rbp # 0x55
push rbx # 0x53
push r12 # 0x41 0x54
push r13 # 0x41 0x55
从AMD64 spec(页313):
PUSH reg64 50 +rq
推一个64位寄存器的上下文压入堆栈。
由于用于rbp
和rbx
的偏移量是5和3,分别为第一两种编码有意义。我不明白是怎么回事的最后两个编码,虽然。
据我所知,0x40-0x4f
是REX前缀和0x41
具有REX.B
位设置(其是延伸到MODRM.rm
或SIB.base
的MSB,根据本external reference)。该规范中提到,访问所有需要使用REX的16个GPR的,但是在截止是,目前还不清楚。
从咨询的MODRM和SIB的文档,我不认为SIB被使用,因为它的目的是利用基地+偏移寄存器索引(不过说实话,我真的不能告诉你只是给MODRM与SIB之间如何区分编码)。
所以,我怀疑这里正在使用MODRM。考虑到只是暂时的push r12
(0x41 0x54
)(并注意到r12
抵消了12
),我们有:
+----------------+--------------------+
| 0x41 | 0x54 |
+----------------+--------------------+
| REX | MODRM |
+--------+-------+-----+--------+-----+
| Prefix | WRXB | mod | reg | rm |
| 0100 | 0001 | 01 | 01 0 | 100 |
+--------+-------+-----+--------+-----+
REX.B + MODRM.rm = 0b1100 = 12
所以这将指示这是源寄存器(r12
=偏移12)。如果忽略所有的表在external (unofficial) reference,REX.R + MODRM.mod + MODRM.reg = 0b00101 = 5
,这是推动教学基地0x50
的前半部分。
所以,我想我已经向后工作,但我不明白,我怎么会在像0x41 0x54
编码到达。从AMD reference,图1-10(页54)具有,如果MODRM.mod = 01 or 10
,则字节一个脚注“包括偏移由指令位移字段中指定”。这将在我们为什么有指令偏移REX.R + MODRM.mod + MODRM.reg = 0b00101 = 5
或许暗示。但是,为什么在指令的MODRM.mod
部分抵消?如果一定要包含比采取这种偏移的形式仅限于前缀0b01
或0x10
指令。这不可能是正确的,对不对?
TL;博士
push
指导工作?push r12
+为0x50 12就像我能为push rbp
或push rbx
?)MODRM.mod
? (或者这是正确的呢?)pop
类似的指令是否一致? (而且我怎么知道哪些指令支持呢?难道它有形式XX +xx
的操作码的所有指令工作?)这里有没有明确的字节ModRM因为整个指令是一个字节。你不能没有操作码字节ModRM。
所述push reg
/ pop reg
短形式嵌入3位寄存器的代码到操作码字节。这是50 + rq
的意思。 (不像FF /6
push r/m64
编码,这确实使用ModRM;你可以编码寄存器操作与使指令长,但通常你会永远只使用了push qword [rdi]
或东西)。
这是相同的格式,16位/ 32位的,这就是为什么需要x86-64的一个额外的位(从REX前缀)来编码“新” /上具有与所述前导比特组4位码寄存器中的一个。
OSdev省略此情况下,只提到ModRM.rm
和SIB.base
。
3.1.1.1 Opcode Column in the Instruction Summary Table (Instructions without VEX Prefix)
- ...
- + RB,+ RW,+ RD,+ RO - 所表示的操作码字节的低3位用于编码未经MODR / M字节的寄存器操作数。指令列出了与低3位为000B操作码字节的相应十六进制值。在非64位模式中,寄存器的代码,从0到7,被添加到操作码字节的十六进制值。在64位模式下,指示REX.b的四位字段和操作码[2:0]字段编码的指令的寄存器操作数。 “+ RO”仅在64位模式下是适用的。表3-1中的代码。
表3-1使用相同的编码方案中ModRM和SIB,勿庸置疑寄存器的数字,但英特尔锐意进取和对所有操作数尺寸的所有整数寄存器的全表。包括AH / BH / CH / DH,因为mov ah, 1
可以使用2个字节的短形式。
我摘录自“四字寄存器(64位模式只)”列中的相关行:
From Intel's Table 3-1. Register Codes Associated With +rb, +rw, +rd, +ro
reg REX.B Reg Field
RBX None 3
RBP None 5
R12 Yes 4
R13 Yes 5
有趣的事实:在Intel的手册,他们实际使用50 + rd
代替50 + ro
为PUSH r64
,一样在32位模式push r32
。 https://www.felixcloutier.com/x86/push。
这是为喜欢流行类似的指令是否一致? (而且我怎么知道哪些指令支持这个吗?它对于具有形式的操作码的所有指令工作XX + XX?)
是。 push/pop reg
,mov reg,imm
,和xchg eax, r32
/ xchg rax, r64
所有使用具有3操作码位相同的编码来编码的寄存器。
这将是很好,如果我们能有这8个xchg
操作码回更有用的东西(如更紧凑VEX或EVEX前缀在64位模式下),但船舶航行时,AMD玩了保守与AMD64,大多保持机器代码相似尽可能为32位模式。他们没有回收用作REX前缀的0x4?
inc/dec reg
操作码,虽然。