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]