首页 > 代码库 > 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 // 切换默认的操作数的大小;如果默认的操作数大小是WORD(16位),那么切换后就是DWORD(32位);反之,如果默认的操作数大小是DWORD(32位),那么切换后就是WORD(16位)。
让我们再来看一个特例:
B0 FF MOV AL, 0FF
8A C1 MOV AL, CL
看清楚了吗?现在的操作数是AL和CL,加上prefix 66后会如何?
66 B0 FF MOV AL, 0FF
66 8A C1 MOV AL, CL
Faint!没有任何变化!
为什么呢?我们可以猜测一下:也许并不是所有情况下的操作数大小都可以随意改变的。假如这个改变是不允许的,那么它就会被忽略。
2)67 //切换默认的地址大小。请注意:67与66的 分别在于,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)
对于这个Prefix,Intel的文档已经解释得很清楚了,不过它的具体意义对OpCode的格式学习并无任何帮助,有兴趣的读者可以在<<Intel Architecture Software Developer‘s Manual Volume 2: Instruction Set Reference>>的3-387页看到关于它的详细解释。在OpCode的格式学习中,我们只需要知道F0表示的是助记符LOCK就足够了。
ABOUT ModR/M:
ModR/M是由Mod、Reg/Opcode和R/M三个部分组成的。每个部分所占的bit大小为(2:3:3):
Mod: 占最高位的6~7共2个bit
Reg/Opcode: 占中间位的3~5共3个bit
R/M: 占最低位的0~2共3个bit
REG && Register
REGRegister
000EAX
001ECX
010EDX
011EBX
100ESP
101EBP
110ESI
111EDI
Mod: 11 表示应该查看Mod为11的那一栏
Reg/Opcode: 111 表示的是寄存器EDI
R/M: 001 表示的是ECX