提到编码,只要学过一点汇编的人都应该知道一些常用的汇编指令的编码,比如:B8 78 56 34 12,一看到B8就知道对应的汇编指令是MOV EAX,0X12345678 占用5字节,一看到E8就知道是E8后面跟的是JMP的4字节偏移,一见90就知道是NOP,因为这些指令都很常用,编码也都很简单,想必大家对这些指令编码都熟记于心了。如果提到 MOV EBX,XXXXXXXX MOV ECX,XXXXXXX这些指令也许大家对指令编码就不怎么记得了,因为X86的编码太多了,要把他全记住那可不是件容易的事。其实要把X86的编码指令记住并不是件难事,因为X86编码指令看似复杂庞大,其实这大部分编码有是有规律可寻的。
在这里先说组寄存器:
0 1 2 3 4 5 6 7
EAX ECX EDX EBX ESP EBP ESI EDI
0 1 2 3 4 5 6 7
AL CL DL BL AH CH DH BH
不知道各位同学当年学汇编的时候寄存器是不是按这个顺序记的,如果是按这个顺序记住的话,接下来讲的编码你可能一看就记住了
B8是MOV EAX 大家都很清楚的记得,那么B9呢?B9就是MOV ECX ,BA MOV EDX 聪明的同学应该很快的看出规律出来了吧!BB 是MOV EBX ,BC是MOV ESP 一直到BF 是MOV EDI
B0是MOV AL,XX 2字节立即数,对照上面的表格,大家应该很容易的说出B1是MOV CL,XX,一直到B7是MOV BH,XX
90是NOP大家都知道,其实他的真正编码指令是XCHG EAX,EAX,91 XCHG EAX,ECX 一直到97 XCHG EAX,EDI
40到47是INC EAX 到 INC EDI ,48到4F是DEC EAX到DEC EDI
50到57是PUSH EAX 到 PUSH EDI ,58到 5F是 POP EAX 到 POP EDI
现在对于这一类的指令编码,大家是不是感觉记起来轻松了
对内存访问的指令在汇编中也经常出现,现在在说说这些指令的编码格式
ADD OR ADC SBB AND SUB XOR CMP
ES CS SS DS
DAA DAS AAA AAS
就跟上面我说的寄存器一样先按顺序记下这些东西再说
要讲对内存访问的编码就不得不先说说X86通用的编码指令格式

上图参考INTEL开发手册卷二,想具体了解的可以去参考下,看不懂英文的,论坛的翻译版块有部分章节的翻译。大家可以去找找
Opcode(操作码),之前所说的B8 XX XX XX XX指令B8就代表Opcode(操作码),之后跟的是4字节的Immediate (立即数),一看到B8开头的编码,就要知道B8代表Opcode,后面带有4字节Immediate的属性
在举个列子,B0 XX,B0代表 Opcode,后面带有1字节Immediate的属性
00 是ADD EB,GB (EB代表1字节内存,GB代表8位寄存器)
碰到00编码,00代表着Opcode(操作码),后面的第2个1字节编码就代表着ModR/M
编码 对应的汇编指令
ModR/M字节的二进制6 7位MOD为0
00 00 ADD BYTE PTR DS:[EAX],AL
00 01 ADD BYTE PTR DS:[ECX],AL
。。。。。
00 07 ADD BYTE PTR DS:[EDI],AL
00 08 ADD BYTE PTR DS:[EAX],CL
。。。。
00 0F ADD BYTE PTR DS:[EDI],CL
00 10 ADD BYTE PTR DS:[EAX],DL
。。。。
00 3F ADD BYTE PTR DS:[EDI],BH
ModR/M字节的二进制6 7位MOD为1,第三个编码为1字节Displacement
00 40 XX ADD BYTE PTR DS:[EAX+XX],AL
00 41 XX ADD BYTE PTR DS:[ECX+XX],AL
。。。。
00 7F XX ADD BYTE PTR DS:[EDI+XX],BH
ModR/M字节的二进制6 7位MOD为2, 从第三个编码开始为4字节Displacement
00 80 XX XX XX XX ADD BYTE PTR DS:[EAX+XXXXXXXX],AL
00 81 XX XX XX XX ADD BYTE PTR DS:[ECX+XXXXXXXX],AL
00 BF XX XX XX XX ADD BYTE PTR DS:[EDI+XXXXXXXX],BH
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课