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指令解析相关推荐

  1. XCP实战系列介绍16-XCP标定过程指令解析

    本文框架 1.前言 2. XCP标定过程指令解析 1.前言 前面几篇文章我们介绍了XCP底层原理,配置方法及基于CANape,CANoe或Vehicle SPY进行观测或标定的方法,在本篇中我们将对标 ...

  2. 解读乐鑫 AT 指令解析器,解锁你不知道的用法

    文章首发于 『物联网学前班』公众号,欢迎关注.星标获取即时信息. 由于近期正好在做这个事情,所以今天就以乐鑫的 AT 指令为例,讲讲 AT 解析器设计有哪些事情,也算是个自己近期的学习总结了. 往期文 ...

  3. CPU指令解析及函数调用机制

    目录 一.CPU指令解析 最常用的mov指令 对栈进行push和pop 二.函数的调用机制 一.CPU指令解析 最常用的mov指令 指令中最常使用的是对寄存器和内存进行数据存储的 mov 指定数据的存 ...

  4. Windows BAT脚本常用指令解析

    BAT脚本入门 一.概述 首先解决第一个问题,什么是BAT脚本? BAT脚本也叫批处理文本,批处理文件是无格式的文本文件,它包含一条或多条命令.它的文件扩展名为 .bat 或 .cmd.在命令提示下键 ...

  5. jvm中篇-04-Javap指令解析class文件

    jvm中篇-04-Javap指令解析class文件 解析字节码的作用 javac -g 操作 javap 的具体用法 使用举例 小结 234-237 解析字节码的作用 通过反编译生成的字节码文件,我们 ...

  6. 17.4 class文件结构 - 使用javap指令解析Class文件

    使用javap指令解析Class文件 解析字节码的作用 通过反编译生成的字节码文件,我们可以深入的了解java代码的工作机制.但是,自己分析类文件结构太麻烦了!除了使用第三方的jclasslib工具之 ...

  7. 记: 对于SCPI指令以及相同类型指令解析器的指令压缩方式

    0x10 前言 SCPI是一个对人或者说用户十分友好的语言,采用了人性化的抽象与对于用户很友善的组成方式. 但是对于某些机器的设计就会很难受,而且当前的机器会在日后的不停更新导致当前的程序越来越呈现一 ...

  8. 单片机at指令解析 开源_分享Github上几个开源单片机硬件驱动库

    Github上的项目基本上以软件为主,硬件的很少,优秀的硬件开源项目更少.单片机的开发中驱动模块化带来的好处是移植方便,不依赖于硬件,但是与裸机开发相比代码复杂不易理解.所以驱动.组件等封装的功能完善 ...

  9. 使用javap指令解析Class文件

    接卸字节码的作用 通过反编译生成的字节码文件,我们可以深入的了解Java代码的工作机制.但是,自己分析类文件结构太麻烦了!除了使用第三方的jclasslib工具之外,oracle官方也提供了工具:ja ...

最新文章

  1. 学完python基础开始学爬虫_零基础入门Python爬虫不知道怎么学?这是入门的完整教程...
  2. 主流框架中DOMContentLoaded事件的实现
  3. Java Lambdas和低延迟
  4. 慎用PHP $_REQUEST数组
  5. Docker Compose运行MySQL、Redis服务
  6. Mac 配置vscode调试PHP
  7. Centos7下SRS流式服务器搭建、推流、拉流
  8. 【生活智慧】001.追求实在的东西
  9. 2020-09-08风扇并联与串联应用学习
  10. 从勒索病毒加密的SQLServer数据库中恢复数据
  11. python爬楼梯算法_Python算法:如何解决楼梯台阶问题
  12. Python相关分析—一个金融场景的案例实操
  13. FLASH编程与改变程序(代码)存储地址的问题
  14. Manjaro第二天
  15. Tomcat HTTP的端口号和redirectPort(重定向)端口号
  16. logging level级别
  17. 中国首个中小学人工智能教材出版,在上海、山东发布
  18. 智能肛珠作弊案反转:19岁小将告世界冠军诽谤索赔7亿
  19. Python 京东抢购茅台脚本(亲测可用)
  20. python字符串高效拼接

热门文章

  1. mongoDB存视频和mysql存视频_数据库存储方式:MySQL存储、MONGODB存储、Redis存储、json存储、视频存储、图片存储...
  2. amigo幸运字符什么意思_Python正则表达式之初始篇:字符匹配
  3. amigo幸运字符什么意思_史上最全python字符串操作指南
  4. AXI协议详解(1)-协议简介
  5. 移动设备管理(MDM)有哪些关键功能?
  6. 举例来学cond原语
  7. Mohican_4/6 C语言 移位运算 代码#FloatToInt
  8. tp对接抖音sdk_Thinkphp集成抖音SDK的实现方法
  9. 证券运维外包第3个月工作总结
  10. cocos2d-x 全面总结--字体描边和制作阴影