Opcode指令解析

2.1            实模式,保护模式,以及虚拟8086模式指令格式

Intel-64IA-32架构指令编码是图2-1所示格式的子集.一条指令包括可选的指令前缀(顺序任意),主操作码(最多3字节),ModR/MSIB字节(可选) 组成的地址格式描述符(如果需要的话),偏移量(可选)以及立即数(可选).

 

前缀

 

主操作码

 

ModR/M

 

SIB

 

偏移量

 

立即数

2.1.1          指令前缀

指令前缀分为四组,每一组包含一些允许的前缀码.对于任何指令,前缀可以从这四组(1,2,3,4)里的挑选,并且它们不区分次序.

•   1

—  锁定和重复前缀:

•    F0H - LOCK

•    F2H - REPNE/REPNZ,仅用于串操作和I/O指令,也可被用作某些指令的强制性前缀

•    F3H - REPREPE/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,23字节. 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/MSIB编码详见第2.1.5.

2.1.4          偏移量 立即数 字节

某些地址构成包含ModR/M以及紧随ModR/M其后的偏移量(或者是SIB字节).如果需要偏移量,它可以是1,2,或者4字节.

若指令指定一个立即操作数,该操作数总是在偏移量之后,立即操作数可以为1,2,4字节.

2.1.5          ModR/MSIB字节寻址模式编码

2-1至表2-3列出了ModR/MSIB字节和寻址模式的对应情况:2-1列出的是16地址模式的情形,而表2-2则是32的情况,2-3则是由SIB字节指定的32位地址的情况.在附录B中列出了当ModR/Mreg/opcode域表现为操作码扩展时的编码情况.

在表2-12-2,指定了由Mod域和R/M域组合的32种有效地址形式,其中前24个是内存操作数,8(mod=11B)是供通用寄存器,MMX以及XMM寄存器使用.

2-12-2中的ModR/M列给出了第一列对应有效地址时ModR/M的值.例如:Mod=11B,R/M=000B,该行确定通用寄存器EAX,AXAL,MMX寄存器MM0,或者XMM寄存器XMM0.最终使用的寄存器由操作码字节以及操作数尺寸属性决定.

现在看看表2-12-2的第7(“REG=”),当需要指定第二操作数时,该行指定Reg/Opcode域的用途,该操作数必须为通用寄存器或者MMX,XMM寄存器,第一至五行为对应的寄存器,同样的,最终使用的寄存器由操作码字节以及操作数尺寸属性决定.

若指令不需要第二操作数,Reg/Opcode可能被用作操作码扩展,即第六行”/digit(Opcode)”所指,以十进制数的形式表示.

2-12-2的主体(” ModR/M (十六进制)”)是一个32*8的矩阵,囊括了ModR/M256个可能值.由位3-5索引列,0-26,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 SIB3,4,5)对应的寄存器及倍率因子(scaling factor SIB byte6,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位的偏移量;否则表示disp8disp32 + [EBP].即提供如下的寻址方式:

MOD          有效地址

00                   [scaled index] + disp32

01                   [scaled index] + disp8 + [EBP]

10                   [scaled index] + disp32 + [EBP]

猜你喜欢

转载自blog.csdn.net/zzy1448331580/article/details/90600014
今日推荐