Opcode指令解析
2.1 实模式,保护模式,以及虚拟8086模式指令格式
Intel-64和IA-32架构指令编码是图2-1所示格式的子集.一条指令包括可选的指令前缀(顺序任意),主操作码(最多3字节),由ModR/M和SIB字节(可选) 组成的地址格式描述符(如果需要的话),偏移量(可选)以及立即数(可选).
前缀 |
主操作码 |
ModR/M |
SIB |
偏移量 |
立即数 |
2.1.1 指令前缀
指令前缀分为四组,每一组包含一些允许的前缀码.对于任何指令,前缀可以从这四组(组1,2,3,4)里的挑选,并且它们不区分次序.
• 组1
— 锁定和重复前缀:
• F0H - LOCK
• F2H - REPNE/REPNZ,仅用于串操作和I/O指令,也可被用作某些指令的强制性前缀
• F3H - REP或REPE/REPZ,仅用于串操作和I/O指令,也可被用作某些指令的强制性前缀
• 组2
— 段重载前缀:
• 2EH—CS 段重载(用于任意分支指令时保留)
• 36H—SS 段重载(用于任意分支指令时保留)
• 3EH—DS 段重载(用于任意分支指令时保留)
• 26H—ES 段重载(用于任意分支指令时保留)
• 64H—FS 段重载(用于任意分支指令时保留)
• 65H—GS 段重载(用于任意分支指令时保留)
— 分支提示:
• 2EH—分支不被接受(仅用于Jcc指令中)
• 3EH—分支被接受(仅用于Jcc指令中)
• 组3
• 66H—操作数大小重载前缀,也可被用作某些指令的强制性前缀.
• 组4
• 67H—地址尺寸重载前缀
LOCK前缀(F0H)在多处理器环境下强制执行独占共享内存操作.详见《Instruction Set Reference, A-M》第三章"LOCK – 断言LOCK#信号前缀".
重复前缀(F2H,F3H)将会重复操作符串的每一个元素.只有MOVS,CMPS,SCAS,LODS,STOS,INS,OUTS等字符串操作或I/O指令才能使用这些前缀. 对Intel 64 或 IA-32 其他指令使用重复前缀和/或未定义的操作码是被保留的,将会引起不可预知的行为.
某些指令可能使用F2H,F3H作为强制性前缀来表示特定的功能.强制性前缀应当位于其他可选的前缀之后(例外的情形请查看第2.2.1节,”REX前缀”)
分支提示前缀(2EH,3EH)允许程序给处理器一个最有可能的执行分支提示.这些前缀只能用于条件指令(Jcc).在Intel 64 或 IA-32 其他指令中使用分支预测前缀或者未定义的操作码是被保留的,将引起不可预知的行为.
操作数大小重载前缀允许程序在16位和32位操作数大小间切换.它们中任一个都可以是默认值,而使用这个前缀则选择非默认值.
某些SSE2/SSE3/SSSE3/SSE4和使用3字节操作码的指令可能使用66H作为强制性前缀来表示特定的功能. 强制性前缀应当位于其他可选的前缀之后(例外的情形请查看第2.2.1节,”REX前缀”) . 66H前缀的其他用法是被保留的, 将引起不可预知的行为.
地址尺寸重载前缀(67H)允许程序在16位和32位地址间切换.它们中的任何一个都可以是默认值,使用这个前缀选择非默认值.当指令中的操作数不在内存中,使用这个前缀或未定义的操作码时,操作被保留,可能引起不可预知的行为.
2.1.2 操作码
主操作码长度为1,2或3字节. ModR/M可能编码附加的3位操作码. 主操作码中定义了一些更小的域.这些域定义了操作方向,偏移大小,寄存器编码,条件代码,或符号扩充.指令使用的域因操作码的类别而不同.
双字节通用和SIMD指令操作码由下面部分组成:
• 转义码(0FH),加上第二个操作码字节,或者
• 一个强制性前缀(66H,F2H,或F3H), 转义码(0FH),第二个操作码字节(和上面一样)
例如,CVTDQ2PD由下面的二进制序列组成:F3 0F E6 .第一个字节是一个SSE/SSE2/SSE3指令的强制性前缀(不被视为重复前缀).
三字节通用和SIMD指令操作码由下面部分组成:
• 转义码(0FH),加上另外2个操作码字节,或者
• 一个强制性前缀(66H,F2H,或F3H), 转义码(0FH),另外2个操作码字节(和上面一样)
比如,XMM寄存器指令PHADDW由下面的二进制序列组成:66 0F 38 01.第一个字节即强制性前缀.
有效的操作码在附录A和附录B中被定义.
2.1.3 ModR/M 和 SIB 字节
许多涉及内存操作数的指令都有一个紧挨着主操作码的寻址格式说明字节(叫做ModR/M字节),ModR/M字节包含3个域信息:
• mod域与r/m域组成32个可能的值:8个寄存器和24个寻址模式.
• reg/opcode域确定寄存器号或者附加的3位操作码.reg/opcode域的用途由主操作码确定.
• r/m域确定一个寄存器为操作数或者和mod域一起编码寻址模式.有时候有些指令使用特定的mod域和r/m域组合来表示操作码信息.
某些ModR/M字节编码需要第二寻址字节(SIB).基址+索引或者比例+索引形式的32位寻址需要SIB字节.SIB字节包括下列域:
• scale 域指定比例因子.
• index域指定索引寄存器号.
• base 域指定基址寄存器号.
ModR/M和SIB编码详见第2.1.5节.
2.1.4 偏移量 和 立即数 字节
某些地址构成包含ModR/M以及紧随ModR/M其后的偏移量(或者是SIB字节).如果需要偏移量,它可以是1,2,或者4字节.
若指令指定一个立即操作数,该操作数总是在偏移量之后,立即操作数可以为1,2,4字节.
2.1.5 ModR/M和SIB字节寻址模式编码
表2-1至表2-3列出了ModR/M和SIB字节和寻址模式的对应情况:表2-1列出的是16位地址模式的情形,而表2-2则是32位的情况,表2-3则是由SIB字节指定的32位地址的情况.在附录B中列出了当ModR/M的reg/opcode域表现为操作码扩展时的编码情况.
在表2-1和2-2中,指定了由Mod域和R/M域组合的32种有效地址形式,其中前24个是内存操作数,后8个(mod=11B)是供通用寄存器,MMX以及XMM寄存器使用.
表2-1和2-2中的Mod和R/M列给出了第一列对应有效地址时Mod和R/M的值.例如:Mod=11B,R/M=000B,该行确定通用寄存器EAX,AX或AL,MMX寄存器MM0,或者XMM寄存器XMM0.最终使用的寄存器由操作码字节以及操作数尺寸属性决定.
现在看看表2-1或2-2的第7行(“REG=”),当需要指定第二操作数时,该行指定Reg/Opcode域的用途,该操作数必须为通用寄存器或者MMX,XMM寄存器,第一至五行为对应的寄存器,同样的,最终使用的寄存器由操作码字节以及操作数尺寸属性决定.
若指令不需要第二操作数,Reg/Opcode可能被用作操作码扩展,即第六行”/digit(Opcode)”所指,以十进制数的形式表示.
表2-1和2-2的主体(即” ModR/M值 (十六进制)”)是一个32*8的矩阵,囊括了ModR/M的256个可能值.由位3-5索引列,位0-2和6,7索引列.下图演示了表中的一个值的解析.
Mod |
11 |
|
RM |
000 |
|
/digit (Opcode); |
REG = |
001 |
C8H |
11001000 |
图 2-2. ModR/M (C8H) 值的解析
表 2-1. 带ModR/M 的16位寻址模式
r8(/r) r16(/r) r32(/r) mm(/r) xmm(/r) (In decimal) /digit (Opcode) (In binary) REG = |
AL AX EAX MM0 XMM0 0 000 |
CL CX ECX MM1 XMM1 1 001 |
DL DX EDX MM2 XMM2 2 010 |
BL BX EBX MM3 XMM3 3 011 |
AH SP ESP MM4 XMM4 4 100 |
CH BP1 EBP MM5 XMM5 5 101 |
DH SI ESI MM6 XMM6 6 110 |
BH DI EDI MM7 XMM7 7 111 |
||
有效地址 |
Mod |
R/M |
ModR/M值 (十六进制) |
|||||||
[BX+SI] [BX+DI] [BP+SI] [BP+DI] [SI] [DI] disp162 [BX] |
00 |
000 001 010 011 100 101 110 111 |
00 01 02 03 04 05 06 07 |
08 09 0A 0B 0C 0D 0E 0F |
10 11 12 13 14 15 16 17 |
18 19 1A 1B 1C 1D 1E 1F |
20 21 22 23 24 25 26 27 |
28 29 2A 2B 2C 2D 2E 2F |
30 31 32 33 34 35 36 37 |
38 39 3A 3B 3C 3D 3E 3F |
[BX+SI]+disp8[冯1] 3 [BX+DI]+disp8 [BP+SI]+disp8 [BP+DI]+disp8 [SI]+disp8 [DI]+disp8 [BP]+disp8 [BX]+disp8 |
01 |
000 001 010 011 100 101 110 111 |
40 41 42 43 44 45 46 47 |
48 49 4A 4B 4C 4D 4E 4F |
50 51 52 53 54 55 56 57 |
58 59 5A 5B 5C 5D 5E 5F |
60 61 62 63 64 65 66 67 |
68 69 6A 6B 6C 6D 6E 6F |
70 71 72 73 74 75 76 77 |
78 79 7A 7B 7C 7D 7E 7F |
[BX+SI]+disp16 [冯2] [BX+DI]+disp16 [BP+SI]+disp16 [BP+DI]+disp16 [SI]+disp16 [DI]+disp16 [BP]+disp16 [BX]+disp16 |
10 |
000 001 010 011 100 101 110 111 |
80 81 82 83 84 85 86 87 |
88 89 8A 8B 8C 8D 8E 8F |
90 91 92 93 94 95 96 97 |
98 99 9A 9B 9C 9D 9E 9F |
A0 A1 A2 A3 A4 A5 A6 A7 |
A8 A9 AA AB AC AD AE AF |
B0 B1 B2 B3 B4 B5 B6 B7 |
B8 B9 BA BB BC BD BE BF |
EAX/AX/AL/MM0/XMM0 ECX/CX/CL/MM1/XMM1 EDX/DX/DL/MM2/XMM2 EBX/BX/BL/MM3/XMM3 ESP/SP/AHMM4/XMM4 EBP/BP/CH/MM5/XMM5 ESI/SI/DH/MM6/XMM6 EDI/DI/BH/MM7/XMM7 |
11 |
000 001 010 011 100 101 110 111 |
C0 C1 C2 C3 C4 C5 C6 C7 |
C8 C9 CA CB CC CD CE CF |
D0 D1 D2 D3 D4 D5 D6 D7 |
D8 D9 DA DB DC DD DE DF |
E0 EQ E2 E3 E4 E5 E6 E7 |
E8 E9 EA EB EC ED EE EF |
F0 F1 F2 F3 F4 F5 F6 F7 |
F8 F9 FA FB FC FD FE FF |
注:
1. BP作为索引默认以SS为段寄存器,其他的寻址方式默认以DS段寄存器.
2. “disp16”记号表示ModR/M 后跟随一个16位的偏移量,该偏移量被加至有效地址.
3. “disp8” 记号表示ModR/M 后跟随一个8位的偏移量,该偏移量将被符号扩展,然后被加至有效地址.
表 2-2. 带ModR/M 的32位寻址模式
r8(/r) r16(/r) r32(/r) mm(/r) xmm(/r) (In decimal) /digit (Opcode) (In binary) REG = |
AL AX EAX MM0 XMM0 0 000 |
CL CX ECX MM1 XMM1 1 001 |
DL DX EDX MM2 XMM2 2 010 |
BL BX EBX MM3 XMM3 3 011 |
AH SP ESP MM4 XMM4 4 100 |
CH BP EBP MM5 XMM5 5 101 |
DH SI ESI MM6 XMM6 6 110 |
BH DI EDI MM7 XMM7 7 111 |
||
有效地址 |
Mod |
R/M |
ModR/M值 (十六进制) |
|||||||
[EAX] [ECX] [EDX] [EBX] [--][--]1 disp322 [ESI] [EDI] |
00 |
000 001 010 011 100 101 110 111 |
00 01 02 03 04 05 06 07 |
08 09 0A 0B 0C 0D 0E 0F |
10 11 12 13 14 15 16 17 |
18 19 1A 1B 1C 1D 1E 1F |
20 21 22 23 24 25 26 27 |
28 29 2A 2B 2C 2D 2E 2F |
30 31 32 33 34 35 36 37 |
38 39 3A 3B 3C 3D 3E 3F |
[EAX]+disp83 [ECX]+disp8 [EDX]+disp8 [EBX]+disp8 [--][--]+disp8 [EBP]+disp8 [ESI]+disp8 [EDI]+disp8 |
01 |
000 001 010 011 100 101 110 111 |
40 41 42 43 44 45 46 47 |
48 49 4A 4B 4C 4D 4E 4F |
50 51 52 53 54 55 56 57 |
58 59 5A 5B 5C 5D 5E 5F |
60 61 62 63 64 65 66 67 |
68 69 6A 6B 6C 6D 6E 6F |
70 71 72 73 74 75 76 77 |
78 79 7A 7B 7C 7D 7E 7F |
[EAX]+disp32 [ECX]+disp32 [EDX]+disp32 [EBX]+disp32 [--][--]+disp32 [EBP]+disp32 [ESI]+disp32 [EDI]+disp32 |
10 |
000 001 010 011 100 101 110 111 |
80 81 82 83 84 85 86 87 |
88 89 8A 8B 8C 8D 8E 8F |
90 91 92 93 94 95 96 97 |
98 99 9A 9B 9C 9D 9E 9F |
A0 A1 A2 A3 A4 A5 A6 A7 |
A8 A9 AA AB AC AD AE AF |
B0 B1 B2 B3 B4 B5 B6 B7 |
B8 B9 BA BB BC BD BE BF |
EAX/AX/AL/MM0/XMM0 ECX/CX/CL/MM/XMM1 EDX/DX/DL/MM2/XMM2 EBX/BX/BL/MM3/XMM3 ESP/SP/AH/MM4/XMM4 EBP/BP/CH/MM5/XMM5 ESI/SI/DH/MM6/XMM6 EDI/DI/BH/MM7/XMM7 |
11 |
000 001 010 011 100 101 110 111 |
C0 C1 C2 C3 C4 C5 C6 C7 |
C8 C9 CA CB CC CD CE CF |
D0 D1 D2 D3 D4 D5 D6 D7 |
D8 D9 DA DB DC DD DE DF |
E0 E1 E2 E3 E4 E5 E6 E7 |
E8 E9 EA EB EC ED EE EF |
F0 F1 F2 F3 F4 F5 F6 F7 |
F8 F9 FA FB FC FD FE FF |
注:
1. “[--][--]”记号表示Mod R/M 后跟随有一个SIB字节.
2. “disp32”记号表示Mod R/M(或者SIB,如果出现的话) 后跟随一个32位的偏移量,该偏移量被加至有效地址.
3. “disp8” 记号表示Mod R/M(或者SIB,如果出现的话) 后跟随一个8位的偏移量,该偏移量将被符号扩展,然后被加至有效地址.
表2-3囊括了SIB 的256个可能值(十六进制形式) . 可以作为基的通用寄存器通过表的上部列出,也列出了相应的base域值. 表的主体的每行列出了索引(index SIB的3,4,5位)对应的寄存器及倍率因子(scaling factor SIB byte的6,7位).
表 2-3. 带SIB 的32位寻址模式
r32 (In decimal) Base = (In binary) Base = |
EAX 0 000 |
ECX 1 001 |
EDX 2 010 |
EBX 3 011 |
ESP 4 100 |
[*] 5 101 |
ESI 6 110 |
EDI 7 111 |
||
Scaled Index |
SS |
Index |
SIB 值 (十六进制) |
|||||||
[EAX] [ECX] [EDX] [EBX] none [EBP] [ESI] [EDI] |
00 |
000 001 010 011 100 101 110 111 |
00 08 10 18 20 28 30 38 |
01 09 11 19 21 29 31 39 |
02 0A 12 1A 22 2A 32 3A |
03 0B 13 1B 23 2B 33 3B |
04 0C 14 1C 24 2C 34 3C |
05 0D 15 1D 25 2D 35 3D |
06 0E 16 1E 26 2E 36 3E |
07 0F 17 1F 27 2F 37 3F |
[EAX*2] [ECX*2] [EDX*2] [EBX*2] none [EBP*2] [ESI*2] [EDI*2] |
01 |
000 001 010 011 100 101 110 111 |
40 48 50 58 60 68 70 78 |
41 49 51 59 61 69 71 79 |
42 4A 52 5A 62 6A 72 7A |
43 4B 53 5B 63 6B 73 7B |
44 4C 54 5C 64 6C 74 7C |
45 4D 55 5D 65 6D 75 7D |
46 4E 56 5E 66 6E 76 7E |
47 4F 57 5F 67 6F 77 7F |
[EAX*4] [ECX*4] [EDX*4] [EBX*4] none [EBP*4] [ESI*4] [EDI*4] |
10 |
000 001 010 011 100 101 110 111 |
80 88 90 98 A0 A8 B0 B8 |
81 89 91 89 A1 A9 B1 B9 |
82 8A 92 9A A2 AA B2 BA |
83 8B 93 9B A3 AB B3 BB |
84 8C 94 9C A4 AC B4 BC |
85 8D 95 9D A5 AD B5 BD |
86 8E 96 9E A6 AE B6 BE |
87 8F 97 9F A7 AF B7 BF |
[EAX*8] [ECX*8] [EDX*8] [EBX*8] none [EBP*8] [ESI*8] [EDI*8] |
11 |
000 001 010 011 100 101 110 111 |
C0 C8 D0 D8 E0 E8 F0 F8 |
C1 C9 D1 D9 E1 E9 F1 F9 |
C2 CA D2 DA E2 EA F2 FA |
C3 CB D3 DB E3 EB F3 FB |
C4 CC D4 DC E4 EC F4 FC |
C5 CD D5 DD E5 ED F5 FD |
C6 CE D6 DE E6 EE F6 FE |
C7 CF D7 DF E7 EF F7 FF |
注:
1. “[*]”记号表示:若MOD = 00B表示没有基,且带有一个32位的偏移量;否则表示disp8或disp32 + [EBP].即提供如下的寻址方式:
MOD有效地址
00 [scaled index] + disp32
01 [scaled index] + disp8 + [EBP]
10 [scaled index] + disp32 + [EBP]
Opcode指令解析相关推荐
- XCP实战系列介绍16-XCP标定过程指令解析
本文框架 1.前言 2. XCP标定过程指令解析 1.前言 前面几篇文章我们介绍了XCP底层原理,配置方法及基于CANape,CANoe或Vehicle SPY进行观测或标定的方法,在本篇中我们将对标 ...
- 解读乐鑫 AT 指令解析器,解锁你不知道的用法
文章首发于 『物联网学前班』公众号,欢迎关注.星标获取即时信息. 由于近期正好在做这个事情,所以今天就以乐鑫的 AT 指令为例,讲讲 AT 解析器设计有哪些事情,也算是个自己近期的学习总结了. 往期文 ...
- CPU指令解析及函数调用机制
目录 一.CPU指令解析 最常用的mov指令 对栈进行push和pop 二.函数的调用机制 一.CPU指令解析 最常用的mov指令 指令中最常使用的是对寄存器和内存进行数据存储的 mov 指定数据的存 ...
- Windows BAT脚本常用指令解析
BAT脚本入门 一.概述 首先解决第一个问题,什么是BAT脚本? BAT脚本也叫批处理文本,批处理文件是无格式的文本文件,它包含一条或多条命令.它的文件扩展名为 .bat 或 .cmd.在命令提示下键 ...
- jvm中篇-04-Javap指令解析class文件
jvm中篇-04-Javap指令解析class文件 解析字节码的作用 javac -g 操作 javap 的具体用法 使用举例 小结 234-237 解析字节码的作用 通过反编译生成的字节码文件,我们 ...
- 17.4 class文件结构 - 使用javap指令解析Class文件
使用javap指令解析Class文件 解析字节码的作用 通过反编译生成的字节码文件,我们可以深入的了解java代码的工作机制.但是,自己分析类文件结构太麻烦了!除了使用第三方的jclasslib工具之 ...
- 记: 对于SCPI指令以及相同类型指令解析器的指令压缩方式
0x10 前言 SCPI是一个对人或者说用户十分友好的语言,采用了人性化的抽象与对于用户很友善的组成方式. 但是对于某些机器的设计就会很难受,而且当前的机器会在日后的不停更新导致当前的程序越来越呈现一 ...
- 单片机at指令解析 开源_分享Github上几个开源单片机硬件驱动库
Github上的项目基本上以软件为主,硬件的很少,优秀的硬件开源项目更少.单片机的开发中驱动模块化带来的好处是移植方便,不依赖于硬件,但是与裸机开发相比代码复杂不易理解.所以驱动.组件等封装的功能完善 ...
- 使用javap指令解析Class文件
接卸字节码的作用 通过反编译生成的字节码文件,我们可以深入的了解Java代码的工作机制.但是,自己分析类文件结构太麻烦了!除了使用第三方的jclasslib工具之外,oracle官方也提供了工具:ja ...
最新文章
- 学完python基础开始学爬虫_零基础入门Python爬虫不知道怎么学?这是入门的完整教程...
- 主流框架中DOMContentLoaded事件的实现
- Java Lambdas和低延迟
- 慎用PHP $_REQUEST数组
- Docker Compose运行MySQL、Redis服务
- Mac 配置vscode调试PHP
- Centos7下SRS流式服务器搭建、推流、拉流
- 【生活智慧】001.追求实在的东西
- 2020-09-08风扇并联与串联应用学习
- 从勒索病毒加密的SQLServer数据库中恢复数据
- python爬楼梯算法_Python算法:如何解决楼梯台阶问题
- Python相关分析—一个金融场景的案例实操
- FLASH编程与改变程序(代码)存储地址的问题
- Manjaro第二天
- Tomcat HTTP的端口号和redirectPort(重定向)端口号
- logging level级别
- 中国首个中小学人工智能教材出版,在上海、山东发布
- 智能肛珠作弊案反转:19岁小将告世界冠军诽谤索赔7亿
- Python 京东抢购茅台脚本(亲测可用)
- python字符串高效拼接
热门文章
- mongoDB存视频和mysql存视频_数据库存储方式:MySQL存储、MONGODB存储、Redis存储、json存储、视频存储、图片存储...
- amigo幸运字符什么意思_Python正则表达式之初始篇:字符匹配
- amigo幸运字符什么意思_史上最全python字符串操作指南
- AXI协议详解(1)-协议简介
- 移动设备管理(MDM)有哪些关键功能?
- 举例来学cond原语
- Mohican_4/6 C语言 移位运算 代码#FloatToInt
- tp对接抖音sdk_Thinkphp集成抖音SDK的实现方法
- 证券运维外包第3个月工作总结
- cocos2d-x 全面总结--字体描边和制作阴影