ModRM 与 SIB 设计上的 2 个原则


 

1、 rbp 作为 base 寄存器时,必须以 [base + disp] 形式存在

  这种设计思想大概是基于:rbp 意为 stack base pointer,既然是 base pointer 那么它应要以 base 加上 offset 这种形式存在才合符它的意义。

  基于这点,x86/x64 的编码上是没有 [rbp] 这个寻址模式存的,只有 [rbp + disp8] 和 [rbp + disp32] 这两种形式的寻址模式。

  rbp 作为 base 寄存器,存在于 ModRM.r/m = 101 和 SIB.base = 101

 

(1)在 ModRM 寻址上的表现

ModRM.r/m 可以提供 [base] 寻址模式,即:ModRM.r/m = [rbp] 时

ModRM.r/m 编码表参见:ModRM.r/m 寻址表


★ 当 ModRM.mod = 00 & ModRM.r/m = 101 时

  MocRM.mod = 00 时是对应着 [base] 这种寻址模式,而 ModRM.r/m = 101 时,按照编码规则,它应该对应着 [rbp]

  但是在这个原则下,[rbp] 是不存在的,代替它的是 [disp32] 这个寻址模式,或者是 x64 体系新增的 [rip + disp32] 寻址模式。

 

★ 当 ModRM.mod = 01 & ModRM.r/m = 101 时

  MocRM.mod = 01 时是对应着 [base + disp8] 这种寻址模式。

  此时 ModRM.r/m = 101 时,并不违反规使则,它回到了正常的编码规则,即:它是 [rbp + disp8] 寻址模式。

 

★ 当 ModRM.mod = 10 & ModRM.r/m = 101 时

  MocRM.mod = 10 时是对应着 [base + disp32] 这种寻址模式。

  此时 ModRM.r/m = 101 时,并不违反规使则,它回到了正常的编码规则,即:它是 [rbp + disp32] 寻址模式。

 

 

(2)在 SIB 寻址上的表现

  这和 ModRM 的情况一样,在 ModRM 寻址上 rbp 作为 base 寄存器时,和在 SIB 寻址上 rbp 作为 base 寄存器的情形都是一样的。

 

当 SIB.base = rbp(101)时, 它的编码结果和 ModRM.r/m = rbp(101)时一样的,都取决于 ModRM.mod

SIB.base 编码参见:SIB.base 寻址表


★ 当 ModRM.mod = 00 & SIB.base = 101 时

  此时 SIB.base = [disp32]

  SIB.base 按规则对应 [rbp] 寻址,在这个原则之下,[rbp] 寻址是不存在的,而以 [disp32] 寻址模式代替。

 

★ 当 ModRM.mod = 01 & SIB.base = 101 时

  此时 SIB.base = [rbp + disp8]

  这里按照编码规则是 [base + disp8] 这种寻址模式,并不违反规则。

 

★ 当 ModRM.mod = 10 & SIB.base = 101 时

  此时 SIB.base = [rbp + disp32]

  这里按照编码规则是 [base + disp32] 这种寻址模式,并不违反规则

 

 

2、 rsp 不能作为 index 寄存器,可以做为 base 寄存器

  对于 [base + index * scale + disp] 这种寻址模式,如果 index 寄存器是 rsp 的话,这是不允许的。


那么,当 SIB.index = 100(rsp)时,会发生什么情况呢?

结果是:[base + index * scale + disp] ---> [base]

  去掉 index,只剩下 base,在这种情况下,和 ModRM.r/m 的结果是一样的。

 

 

例1:寻址模式 [rax]

事实上,对于 [rax] 寻址,两种编码方式,分别是:仅使用 ModRM 寻址以及 ModRM + SIB 寻址

★ 仅使用 ModRM 寻址

  这种编码方式是最常用的,绝大部分甚至说全部 assembler 都会编译为这种方式。

  它的编码是:ModRM = 00-XXX-000

 

★ 使用 ModRM + SIB 寻址

  这种编码方式,几乎不会有 assembler 会采用的,因为多了 1 个字节

  最终编码是:ModRM = 00-XXX-100  SIB = 00-100-000

 

 

例2:实际的指令 mov rax, qword ptr [rax]

第 1 种编码结果是:48 8b 00(仅使用 ModRM 字节寻址)

第 2 种编码结果是:48 8b 04 20 (ModRM + SIB,其中:ModRM = 04,SIB = 20)

--------------------------------------------------------------------

这两种编码结果都是正确的,只是通常的 assembler 都是产生第 1 种编码结果,第 2 编码不会有 assembler 会使用的。

 

 

 

3、 [rbp] 寻址的实现

  由于 [rbp] 寻址在编码上是不存在的,那么 assembler 会做些变通处理。

  实际的编码为:[rbp] ---> [rbp + 0x00] 或者 [rbp + 0x00000000]

 

例1: 指令 mov rax, qword ptr [rbp] 它的编码是多少?

如上所述,[rbp] 会变成 [rbp + 0x00] 或者 [rbp + 0x00000000]


下面是使用 2 种版本的编码结果:

(1)仅使用 ModRM 寻址,编码结果是: 48 8b 45 00       (使用 [rbp + disp8] 方式)

               或者是: 48 8b 85 00 00 00 00  (使用 [rbp + disp32] 方式)

 

(2)使用 ModRM + SIB,编码结果是: 48 8b 44 25 00       (使用 SIB 的 [rbp + disp8] 方式)

               或者是: 48 8b 84 25 00 00 00 00  (使用 SIB 的 [rbp + disp32] 方式)

 

 

4、 [rsp] 寻址的实现

  [rsp] 寻址只能通过引导出 SIB,然后在 SIB.base = rsp 来实现。

  SIB 的 3 种方式为:[SIB][SIB + disp8] 以及 [SIB + disp32]

 

例2: 指令 mov rax, qword ptr [rsp] 它的编码是多少?

  通过 ModRM = 00-XXX-100 ([SIB]) 引导出 SIB 字节。

  或者: ModRM = 01-XXX-100 ([SIB + disp8]) 引出 SIB 字节

  或者: ModRM = 10-XXX-100 ([SIB + disp32])引出 SIB 字节

  然后 SIB = 00-100-100 (SIB.base = rsp)

 

最终的编码结果是: 48 8b 04 24 (SIB.base = rsp)

当然也可以这样: 48 8b 44 24 00  (使用 [SIB + disp8] 方式)

     甚至: 48 8b 84 24 00 00 00 00 (使用 [SIB + disp32] 方式)

 

 

5、最后结合 ModRM 与 SIB 举例子


例1:指令 mov rax, qword [r13 + rbp] 编码是多少?

像这样的指令可以有 2 种形式,分别为: base = r13,index = rbp 以及 base = rbp,index = r13

(1)设 base = r13 而 index = rbp 时,编码是多少?

  它的编码为:49 8b 44 2d 00

(2)设 base = rbp 而 r13 = index 时,编码是多少?

  它的编码是:4a 8b 44 2d 00

 

2:指令 mov rax, qword [rbp + r8 * 8] 编码是多少?

  base 是 rbp,这里使用的是: [rbp + 0x00],当然也可使用 [rbp + 0x00000000]

★ 使用 base = [rbp + 0x00] 编码时,它的 encodes 是:4a 8b 44 c5 00

★ 使用 base = [rbp + 0x00000000] 时,它的 encodes 是:4a 8b 84 c5 00 00 00 00

 

 

例3:指令 mov rax, qword [rsp + rbp * 8 + 0x0c] 编码是多少?

  base 是 rsp, 这里使用 [SIB + disp8],当然也可以使用 [SIB + disp32]

★ 使用 base = [SIB + 0x0c] 编码时,它的 encodes 是:48 8b 44 ec 0c

★ 使用 base = [SIB + 0x0000000c] 时,它的 encodes 是:48 8b 84 ec 0c 00 00 00


版权 mik(deng zhi)所有,转载注明出处