http://www.luocong.com/learningopcode/doc/1._什么是OpCode?.htm
OpCode就是Operation Code,意即操作码的意思, 就是010101了。
mnemonic就是我们用的汇编指令, 叫助记符 .
一个OpCode不只对应一个助记符
OpCode mnemonic
0x90 NOP
0x90 XCHG AX, AX
0x90 XCHG EAX, EAX
一个助记符不只对应一个OpCode
mnemonic OpCode
ADD EAX, 1 0x83C001
ADD EAX, 1 0x0501000000
ADD EAX, 1 0x81C001000000
OpCode与mnemonic的关系
一个OpCode不只对应一个mnemonic。
一个mnemonic不只对应一个OpCode。
OpCode的6个域:
1. Prefixes
2. code
3. ModR/M
4. SIB
5. Displacement
6. Immediate
这6个域的先后顺序是固定的, 其中2是必选的, 其他是可选的
OpCode mnemonic
0xC3 RETN
0x2F DAS
0x90 NOP
0xAC LODSB
上表中的几个OpCode都只用到了code这一项。
其中的最后一项:0xAC 我们在它前面加入F3:
0xF3AC REP LODSB
可以看到:rep lodsb
为什么会多了个“rep”呢?
那肯定是因为加了F3的缘故了.
我们来看看它的OpCode格式描述,如下:(注:用{}包围起来的是域的名称)
AC -- {code}
F3 AC -- {Prefix}{code}
因此,F3 就是域 Prefix
F3表示的是Rep Prefix,它也能与movsb,stosb等指令联用, 等等。
看下面例子:
OpCode mnemonic
27 DAA
2F DAS
3F AAS
37 AAA
D40A AAM
D50A AAD
在Intel的文档中,上表中的所有指令都是1字节的,但是,我们能够看到AAM和AAD是2字节的,到底有什么不同呢?
AAM和AAD的OpCode的第2个字节都是0Ah。
AAM和AAD的描述:
AAM : divide al by 10
商 放在AH里
余数 放在AL里
AAD : AL = AH * 10 + AL
注意到了吗?两者的操作都与10有关。而且两者的OpCode的第二个字节都是10(0Ah)。
AAM与AAD的指令格式不是:
D40A for AAM
D50A for AAD
而是:
D4:imm8 for AAM
D5:imm8 for AAD
(imm8表示8位的立即数)
以此类推, 我们可以通过反汇编器得知,D407表示的是AAM 7,D508表示的是AAD 8,以此类推。
现在,我们又知道了一种新的指令格式:
{code}{Immediate}(域2和域6)
(操作符 + 立即数)
虽然并不是6个域都是必要的,但是,它们的排列顺序绝对不能乱,必须严格按照上面的顺序进行。有些域也许不会出现,但是只要出现了,编号小的域就绝对不允许出现在编号大的域的后面,反之亦然。
例如,{Prefix}{code}的顺序绝对不允许变成{code}{Prefix}。