shineyear 发表于 2007-02-26 11:09

翻译一段机器码时遇到的问题

根据INTER IA32手册里

call r32

翻译成机器码 应该是 FF /2

请问这个"/2"   是什么意思呢?

mingyanguo 发表于 2007-02-26 11:20

看手册前面的说明。
这应该是指令的op/reg/mm字段中op字段的值吧,很久没看,记不清了。

mik 发表于 2007-02-26 20:53

intel 和 AMD文档里没有你标识的这种写法

正确的操作数标识法是:

1、CALL Ap   
      代表调用目标直接编码在指令编码里,根据指令格式可能是一个远程调用。

2、CALL Jz
      代表调用目标是 EIP 寄存器的一个偏移量,偏移量根据指令操作数的有效值可以是 16、32 或 64 位

3、CALL Ev
      代表调用目标是内存操作数或者是寄存器操作数,大小依赖有指令数操作有效值。

4、CALL Ep
      代表调用目标是内存操作数或者是寄存器操作数,根据指令格式可能是一个远程调用。


一般情况下,编译器生成的格式是 CALL Jz 这种格式,也就是说目标地址依赖于 EIP值。

象以下这条指令:
   call *%eax

将会产生 CALL Ev 这种编码格式, 以上这条指令的二进制编码是: FF D0


下面我详细讲解一下是如何编译的:

x86 的指令格式是: prefix + opcode + Mod/RM + SIB + Disp + Imme   
指令长度最长是 15 字节,最短是 1 字节。

以 CALL Ev 这种格式编码来讲解:

1、它的 opcode 是 0xff,这个是个特殊的 opcode 它需要配合 Mod/RM 字节。

2、Mod/RM 的格式如下:
    00       000       000
      ---   ----       -----
   Mod      reg      r/m

3、某些 x86 指令编码被分成几个组。 CALL Ev 被分配到 Group 5 里面去,在 Group 5 里的 CALL Ev 这种编码格式它的 Mod/RM中的 /reg 域被固定设为 2。

4、寄存器的编码顺序依次排列为 eax、ecx、edx、ebx、esp、ebp、esi、edi 。它们分别对应于 0、1、2、3、4、5、6、7 共8个编码。

5、根据 Mod/RM 编码表,eax 的编码为:
    mod :11
      reg:   未知
    r/m:   000

6、而 CALL Ev 的 reg 已经固定为 2 ,所以整个操作数 eax 的 Mod/RM 字节编码为:
    mod : 11
      reg:010
      r/m:000

因此,整个 Mod/RM 字节是: 11 010 000   也就是 D0


7、最后 call *%eax这条指令的编码是: FF D0




lz,所说的 call r32 这种格式估计就是 CALL Ev 这种格式, FF /2 中的 /2 是 call 指令被分配到 Group 5 中的第 3 列。注意,这里列是从 0 开始,也就是值 / 2

mik 发表于 2007-02-26 20:56

另外,LZ 可以看看我的 blog 里面有一篇文章是讲如何解析指令的。

shineyear 发表于 2007-03-04 19:02

讲的很详细啊,很有帮助,谢谢
页: [1]
查看完整版本: 翻译一段机器码时遇到的问题