[草稿] 对AbstractAssembler类的emit_byte方法的实现有点不太理解

JianLeiXing 2014-05-10
AbstractAssembler使用emitting byte的方法向CodeBuffer中写入Code。但是对该方法的的输入参数有一点不明白:
比如:
void Assembler::movl(Register dst, Register src) {
  int encode = prefix_and_encode(dst->encoding(), src->encoding());
  emit_byte(0x8B);
  emit_byte(0xC0 | encode);
}

其中0x8B是movl指令的字节码,但是0xC0 | encode这个怎么解释?
RednaxelaFX 2014-05-11
这就是x86的编码方式啊…
0x8B 0xC0 到 0x8B 0xFF 这个范围之内都是32位寄存器到寄存器的mov指令。
0x8B是这个指令的opcode,而后面那个字节是这个指令的operand。

32位x86只有8个通用寄存器,而mov指令允许src和dst是相同的寄存器,也就是说需要编码的operand有8*8=64种可能性,0xC0 + 64 - 1 = 0xFF。
JianLeiXing 2014-05-12
@RednaxelaFX
引用

32位x86只有8个通用寄存器,而mov指令允许src和dst是相同的寄存器,也就是说需要编码的operand有8*8=64种可能性,0xC0 + 64 - 1 = 0xFF。


原来是这样,非常感谢。有没有介绍x86指令编码比较好的资料?
ZHH2009 2014-05-12
这里有x86指令的详细介绍: http://ref.x86asm.net/index.html
JianLeiXing 2014-05-13
今天研究了下指令的编码格式:movl(Register dst, Register src) 它对应的格式应该是

------------  ------------
|操作码  | Mod R/M |
------------  ------------

其中Mod R/M 这个字节的格式如下:

----------------  -------------- --------------
|Mod(6-7位)| Reg(3-5位)|R/M(0-2位)|
----------------  -------------- --------------

Mod:表示寻址方式,其中11代表R/M域为寄存器号
Reg:表示源操作数,如果为BX那么就是011
R/M: 表示目的操作数,如果是AX那么应该是000

所以:
  emit_byte(0x8B);  //Movl操作码的值
  emit_byte(0xC0 | encode); //OxC0代表Mod值为11,encode为Reg和R/M的值
Global site tag (gtag.js) - Google Analytics