首页 > 代码库 > OpCode

OpCode

ABOUT OPCODE

OpCode组成:

 

Prefixes

Code

ModR/M

SIB

Displacement

Immediate

 

以上六个域是可选的(非必须,非线性),但Code域是必须有的;而且排列顺序也不能打乱,如果存在某域必须按照 从左到右 

Prefixes -> Code -> ModR/M -> SIB -> Displacement -> Immediate 排序。

 

About Prefixes:

 

Prefixes的几个特性:

1. 它是唯一的一个可能出现在code之前的域。

2. 所有的Prefixes都只有1个字节。

3. 在一个OpCode中可能会有多个Prefixes

4.一个OpCode中可以有多个Prefixes

5.如果有多个Prefixes,那么它们的顺序可以打乱,不会有任何问题。

6.如果Prefixes不能对随它之后的OpCode起作用,那么它就会被忽略。

 

  Prefixes,它们可以被划分为5个集合,分别是:

1.Change DEFAULT operand size. (66) 

2.Change DEFAULT address size. (67)

3.Repeat prefixes. (F2, F3)

4.Segment override prefixes(change DEFAULT segment). (2E, 36, 3E, 26, 64, 65)

5.LOCK prefix. (F0)

 

1) 66 // 切换默认的操作数的大小;如果默认的操作数大小是WORD16位),那么切换后就是DWORD32位);反之,如果默认的操作数大小是DWORD32位),那么切换后就是WORD16位)。

让我们再来看一个特例:

 

B0 FF    MOV AL, 0FF

8A C1    MOV AL, CL

看清楚了吗?现在的操作数是ALCL,加上prefix 66后会如何?

 

66 B0 FF    MOV AL, 0FF

66 8A C1    MOV AL, CL

Faint!没有任何变化!

 

为什么呢?我们可以猜测一下:也许并不是所有情况下的操作数大小都可以随意改变的。假如这个改变是不允许的,那么它就会被忽略。

 

2)67 //切换默认的地址大小。请注意:6766的 分别在于,66改变的是默认的操作数大小,而67则是地址的大小。

3)F2/F3   rep[F3]repe[F3]repne[F2]

4)2E, 36, 3E, 26, 64, 65 //用来改变默认的段

Prefix Explanation

2E CS segment override prefix

36 SS segment override prefix

3E DS segment override prefix

26 ES segment override prefix

64 FS segment override prefix

65 GS segment override prefix

5)LOCK Prefix (F0)

对于这个PrefixIntel的文档已经解释得很清楚了,不过它的具体意义对OpCode的格式学习并无任何帮助,有兴趣的读者可以在<<Intel Architecture Software Developer‘s Manual Volume 2: Instruction Set Reference>>3-387页看到关于它的详细解释。在OpCode的格式学习中,我们只需要知道F0表示的是助记符LOCK就足够了。

 

ABOUT ModR/M:

ModR/M是由ModReg/OpcodeR/M三个部分组成的。每个部分所占的bit大小为(2:3:3)

       Mod: 占最高位的672bit

     Reg/Opcode: 占中间位的353bit

       R/M: 占最低位的023bit

 

REG && Register

REGRegister

000EAX

001ECX

010EDX

011EBX

100ESP

101EBP

110ESI

111EDI

 

Mod: 11  表示应该查看Mod11的那一栏

Reg/Opcode: 111 表示的是寄存器EDI

R/M: 001 表示的是ECX