PUSH的英特尔REX编码

问题描述 投票:5回答:1

GAS给出了以下说明以下编码:

push rbp    # 0x55
push rbx    # 0x53
push r12    # 0x41 0x54
push r13    # 0x41 0x55

AMD64 spec(页313):

PUSH reg64 50 +rq推一个64位寄存器的上下文压入堆栈。

由于用于rbprbx的偏移量是5和3,分别为第一两种编码有意义。我不明白是怎么回事的最后两个编码,虽然。

据我所知,0x40-0x4f是REX前缀和0x41具有REX.B位设置(其是延伸到MODRM.rmSIB.base的MSB,根据本external reference)。该规范中提到,访问所有需要使用REX的16个GPR的,但是在截止是,目前还不清楚。

从咨询的MODRM和SIB的文档,我不认为SIB被使用,因为它的目的是利用基地+偏移寄存器索引(不过说实话,我真的不能告诉你只是给MODRM与SIB之间如何区分编码)。

所以,我怀疑这里正在使用MODRM。考虑到只是暂时的push r120x41 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) referenceREX.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部分抵消?如果一定要包含比采取这种偏移的形式仅限于前缀0b010x10指令。这不可能是正确的,对不对?

TL;博士

  • 如何在REX编码实际上像push指导工作?
  • 什么是需要一个REX前缀的指令偏移截止? (是它记录的是我不能做push r12 +为0x50 12就像我能为push rbppush rbx?)
  • 为什么包含在指令基地的前缀MODRM.mod? (或者这是正确的呢?)
  • 这是对于像pop类似的指令是否一致? (而且我怎么知道哪些指令支持呢?难道它有形式XX +xx的操作码的所有指令工作?)
  • 这哪里是记录在官方手册?
  • 我怎么能区分一个REX前缀是否后跟MODRM或SIB字节?
  • 是否有更好的文档,也许这些奠定了工艺步骤,而不是让你几个页面之间跳转,从桌到桌的?
assembly x86-64 intel gas machine-code
1个回答
4
投票

这里有没有明确的字节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.rmSIB.base


英特尔册手册PDF文档的编码:

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 + roPUSH r64,一样在32位模式push r32https://www.felixcloutier.com/x86/push


这是为喜欢流行类似的指令是否一致? (而且我怎么知道哪些指令支持这个吗?它对于具有形式的操作码的所有指令工作XX + XX?)

是。 push/pop regmov reg,imm,和xchg eax, r32 / xchg rax, r64所有使用具有3操作码位相同的编码来编码的寄存器。

这将是很好,如果我们能有这8个xchg操作码回更有用的东西(如更紧凑VEX或EVEX前缀在64位模式下),但船舶航行时,AMD玩了保守与AMD64,大多保持机器代码相似尽可能为32位模式。他们没有回收用作REX前缀的0x4? inc/dec reg操作码,虽然。

© www.soinside.com 2019 - 2024. All rights reserved.