2024年4月2日发(作者:)

汇编指令机器码总结与验证

摘 要:本文介绍了汇编指令机器码的含义与作用,并讨论了指令的组成结构即操作码与地址码。

然后全面总结了机器码中的单字节操作码,并利用Debug工具进行了详细的验证。

关键词:指令;机器码

一、机器码概述

[1]

机器语言是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集合。这种指令

集就称为机器码,它是电脑的CPU可直接解读的数据。一条指令是机器语言的一个语句,是一组

有意义的二进制代码。计算机通过执行指令来处理各种数据。

为了指出数据的来源、操作结果的去向及所执行的操作,一条指令必须包含下列信息:

a) 操作码

b) 操作数的地址

c) 操作结果的存储地址

d) 下条指令的地址

一条指令实际上包括两种信息即操作码和地址码。操作码用来表示该指令所要完成的操作(如

加、减、乘、除、数据传送等),其长度取决于指令系统中的指令条数。地址码用来描述该指令的操

作对象,它或者直接给出操作数,或者指出操作数的存储器地址或寄存器地址(即寄存器名)。

二、机器码详解

[2]

由上文已知,一条指令一般由操作码和地址码组成。其中,操作码是指明CPU对内存或寄存器

中的数据进行什么样的操作,地址码给出这些数据对象。下面我们就将指令分为两部分进行研究。

1.操作码

操作码一般占用1个字节(8位)或2个字节(16位)。其中最低比特(记作W)在很多指令

中表示目标操作数的位宽,W=0表示字节长(8位)操作数,W=1表示双字节长(16位)操作数。

例如,操作码00000000B(W=0)表示“ADD 8位寄存器,8位寄存器”,而00000001B(W=1)表

示“ADD 16位寄存器,16位寄存器”。

2.地址码

地址码一般占用1个字节,其中的8个比特位可分为三组,形式一般为“oommmrrr”。这些分

1) “oo”——表示指令的地址偏移量类型

a) 00:如果mmm=110,那么指令后紧跟一个地址偏移量;否则未使用地址偏移量

b) 01:指令后紧跟一个8比特无符号地址偏移量

c) 10:指令后紧跟一个16比特无符号地址偏移量

d) 11:此时mmm表示一个寄存器而不是地址

组大致可分为以下四个类型:

2) “mmm”——表示存储器操作数地址

a) 000 : DS:[BX+SI]

b) 001 : DS:[BX+DI]

c) 010 : SS:[BP+SI]

d) 011 : SS:[BP+DI]

e) 100 : DS:[SI]

f) 101 : DS:[DI]

g) 110 : SS:[BP]

h) 111 : DS:[BX]

3) “rrr”——表示通用寄存器(下列分别表示当W=0;W=1;32位)

a) 000:AL:AX:EAX

b) 001:CL:CX:ECX

c) 010:DL:DX:EDX

d) 011:BL:BX:EBX

e) 100:AH:SP:ESP

f) 101:CH:BP:EBP

g) 110:DH:SI:ESI

h) 111:BH:DI:EDI

4) “sss”——表示段寄存器

a) 000 : ES

b) 001 : CS

c) 010 : SS

d) 011 : DS

e) 100 : FS (386+)

f) 101 : GS (386+)

三、操作码总结与验证

[3]

从上一节可以看出,一条指令的操作码变化有限(8比特操作码只有不超过256个)而且相对地

址码更为重要,因此这一节我们重点讨论单字节指令的操作码。为描述指令类型,我们约定了不同

类型寄存器、内存和立即数等操作数的符号,见表1。

表1 操作数符号

符号

reg8

reg16

mem8

mem16

类型说明

8位寄存器

16位寄存器

8位内存数值

16位内存数值

符号

imm8

imm16

imm32

seg

类型说明

8位立即数值

16位立即数值

32位立即数值

16位段寄存器

为了方便验证操作码,我们将在验证时填充地址码为0x00。下面,我们就按照单字节操作码的

比特顺序进行总结与验证。首先,我们列出机器码为0x0n的16个操作码,见表2。

表2 0x0n机器码及对应指令

机器码

00

01

02

03

04

05

06

07

08

09

0A

0B

0C

0D

0E

0F

汇编指令

ADD reg8/mem8,reg8

ADD reg16/mem16,reg16

ADD reg8,reg8/mem8

ADD reg16,reg16/mem16

ADD AL,imm8

ADD AX,imm16

PUSH ES

POP ES

OR reg8/mem8,reg8

OR reg16/mem16,reg16

OR reg8,reg8/mem8

OR reg16,reg16/mem16

OR AL,imm8

OR AX,imm16

PUSH CS

Not used

利用Debug工具进行验证,依次输入16条指令的16进制代码(地址码均为0x00),然后使用

“-u”查看指令,如图1。

图1 0x0n机器码验证

从图中可以看出,我们验证的结果与理论值完全一致。

接下来,我们将重复以16条指令为单位,依次列出指令机器码,并进行验证。

机器码为0x1n的16个操作码,见表3。

表3 0x1n机器码及对应指令

机器码

10

11

12

13

14

15

16

17

18

19

1A

1B

1C

1D

1E

1F

验证结果见图2。

汇编指令

ADC reg8/mem8,reg8

ADC reg16/mem16,reg16

ADC reg8,reg8/mem8

ADC reg16,reg16/mem16

ADC AL,imm8

ADC AX,imm16

PUSH SS

POP SS

SBB reg8/mem8,reg8

SBB reg16/mem16,reg16

SBB reg8,reg8/mem8

SBB reg16,reg16/mem16

SBB AL,imm8

SBB AX,imm16

PUSH DS

POP DS

图2 0x1n机器码验证

从图中可以看出,我们验证的结果与理论值完全一致。

机器码为0x2n的16个操作码,见表4。

表4 0x2n机器码及对应指令

机器码

20

21

22

23

24

25

26

27

28

29

2A

2B

2C

2D

2E

2F

验证结果见图3。

汇编指令

AND reg8/mem8,reg8

AND reg16/mem16,reg16

AND reg8,reg8/mem8

AND reg16,reg16/mem16

AND AL,imm8

AND AX,imm16

Segment override

DAA

SUB reg8/mem8,reg8

SUB reg16/mem16,reg16

SUB reg8,reg8/mem8

SUB reg16,reg16/mem16

SUB AL,imm8

SUB AX,imm16

Segment override

DAS

图3 0x2n机器码验证

从图中可以看出,我们验证的结果与理论值完全一致,并且指令0x26和0x2E分别是重载段寄

存器DS和CS。

机器码为0x3n的16个操作码,见表5。

表5 0x3n机器码及对应指令

机器码

30

31

32

33

34

35

36

37

38

39

3A

3B

3C

3D

3E

3F

验证结果见图4。

汇编指令

XOR reg8/mem8,reg8

XOR reg16/mem16,reg16

XOR reg8,reg8/mem8

XOR reg16,reg16/mem16

XOR AL,imm8

XOR AX,imm16

Segment override

AAA

CMP reg8/mem8,reg8

CMP reg16/mem16,reg16

CMP reg8,reg8/mem8

CMP reg16,reg16/mem16

CMP AL,imm8

CMP AX,imm16

Segment override

AAS

图4 0x3n机器码验证

从图中可以看出,我们验证的结果与理论值完全一致,并且指令0x36和0x3E分别是重载段寄

存器SS和DS。

机器码为0x4n的16个操作码,见表6。

表6 0x4n机器码及对应指令

机器码

40

41

42

43

44

45

46

47

48

49

4A

4B

4C

4D

4E

4F

验证结果见图5。

汇编指令

INC AX

INC CX

INC DX

INC BX

INC SP

INC BP

INC SI

INC DI

DEC AX

DEC CX

DEC DX

DEC BX

DEC SP

DEC BP

DEC SI

DEC DI

图5 0x4n机器码验证

从图中可以看出,我们验证的结果与理论值完全一致。

机器码为0x5n的16个操作码,见表7。

表7 0x5n机器码及对应指令

机器码

50

51

52

53

54

55

56

57

58

59

5A

5B

5C

5D

5E

5F

验证结果见图6。

汇编指令

PUSH AX

PUSH CX

PUSH DX

PUSH BX

PUSH SP

PUSH BP

PUSH SI

PUSH DI

POP AX

POP CX

POP DX

POP BX

POP SP

POP BP

POP SI

POP DI

图6 0x5n机器码验证

从图中可以看出,我们验证的结果与理论值完全一致。

机器码为0x6n的16个操作码,见表8。

表8 0x6n机器码及对应指令

机器码

60

61

62

63

64

65

66

67

68

69

6A

6B

6C

6D

6E

6F

验证结果见图7。

PUSHA

POPA

汇编指令

BOUND reg16/mem16,reg16

Not used

Not used

Not used

Not used

Not used

PUSH imm16

IMUL reg16/mem16,imm16

PUSH imm8

IMUL reg8/mem8,imm8

INSB

INSW

OUTSB

OUTSW

图7 0x6n机器码验证

从图中可以看出,这一组指令在80x86架构CPU中都不存在,所以CPU自动将其翻译为数据。

机器码为0x7n的16个操作码,见表9。

表9 0x7n机器码及对应指令

机器码

70

71

72

73

74

75

76

77

78

79

7A

7B

7C

7D

7E

7F

验证结果见图8。

汇编指令

JO imm8

JNO imm8

JB imm8

JNB imm8

JZ imm8

JNZ imm8

JBE imm8

JA imm8

JS imm8

JNS imm8

JP imm8

JNP imm8

JL imm8

JNL imm8

JLE imm8

JG imm8

图8 0x7n机器码验证

从图中可以看出,我们验证的结果与理论值完全一致。

机器码为0x8n的16个操作码,见表10。

表10 0x8n机器码及对应指令

机器码

80

81

82

83

84

85

86

87

88

89

8A

8B

8C

8D

8E

8F

验证结果见图9。

Table2 reg8

Table2 reg16

Table2 reg8

汇编指令

Table2 reg8, reg16

TEST reg8/mem8,reg8

TEST reg16/mem16,reg16

XCHG reg8,reg8

XCHG reg16,reg16

MOV reg8/mem8,reg8

MOV reg16/mem16,reg16

MOV reg8,reg8/mem8

MOV reg16,reg16/mem16

MOV reg16/mem16,seg

LEA reg16,reg16/mem16

MOV seg,reg16/mem16

POP reg16/mem16

图9 0x8n机器码验证

从图中可以看出,我们验证的结果除了80x86架构CPU不存在的0x80-0x83指令之外,其余指

令与理论值完全一致。

机器码为0x9n的16个操作码,见表11。

表11 0x9n机器码及对应指令

机器码

90

91

92

93

94

95

96

97

98

99

9A

9B

9C

9D

9E

9F

验证结果见图10。

汇编指令

NOP

XCHG AX,CX

XCHG AX,DX

XCHG AX,BX

XCHG AX,SP

XCHG AX,BP

XCHG AX,SI

XCHG AX,DI

CBW

CWD

CALL imm32

WAIT

PUSHF

POPF

SAHF

LAHF

图10 0x9n机器码验证

从图中可以看出,我们验证的结果与理论值完全一致。

机器码为0xAn的16个操作码,见表12。

表12 0xAn机器码及对应指令

机器码

A0

A1

A2

A3

A4

A5

A6

A7

A8

A9

AA

AB

AC

AD

AE

AF

验证结果见图11。

汇编指令

MOV AL,[mem8]

MOV AX,[mem16]

MOV [mem8],AL

MOV [mem16],AX

MOVSB

MOVSW

CMPSB

CMPSW

TEST AL,[mem8]

TEST AX,[mem16]

STOSB

STOSW

LODSB

LODSW

SCASB

SCASW

图11 0xAn机器码验证

从图中可以看出,我们验证的结果与理论值完全一致。

机器码为0xBn的16个操作码,见表13。

表13 0xBn机器码及对应指令

机器码

B0

B1

B2

B3

B4

B5

B6

B7

B8

B9

BA

BB

BC

BD

BE

BF

验证结果见图12。

汇编指令

MOV AL,imm8

MOV CL,imm8

MOV DL,imm8

MOV BL,imm8

MOV AH,imm8

MOV CH,imm8

MOV DH,imm8

MOV BH,imm8

MOV AX,imm16

MOV CX,imm16

MOV DX,imm16

MOV BX,imm16

MOV SP,imm16

MOV BP,imm16

MOV SI,imm16

MOV DI,imm16

图12 0xBn机器码验证

从图中可以看出,我们验证的结果与理论值完全一致。

机器码为0xCn的16个操作码,见表14。

表14 0xCn机器码及对应指令

机器码

C0

C1

C2

C3

C4

C5

C6

C7

C8

C9

CA

CB

CC

CD

CE

CF

验证结果见图13。

Table1 reg8

汇编指令

Table1 reg8, reg16

RET imm16 NEAR

RET NEAR

LES reg16/mem16,mem16

LDS reg16/mem16,mem16

MOV reg8/mem8,imm8

MOV reg16/mem16,imm16

ENTER imm16,imm8

LEAVE

RET imm16 FAR

RET FAR

INT 3

INT imm8

INTO

IRET

图13 0xCn机器码验证

从图中可以看出,我们验证的结果除了80x86架构CPU不存在的0xC0、0xC1、0xC8和0xC9指

令之外,其余指令与理论值完全一致。

机器码为0xDn的16个操作码,见表15。

表15 0xDn机器码及对应指令

机器码

D0

D1

D2

D3

D4

D5

D6

D7

D8

D9

DA

DB

DC

DD

DE

DF

验证结果见图14。

汇编指令

Table1 reg8

Table1 reg16

Table1 reg8

Table1 reg16

AAM

AAD

Not used

XLAT [BX]

ESC imm8

ESC imm8

ESC imm8

ESC imm8

ESC imm8

ESC imm8

ESC imm8

ESC imm8

图14 0xDn机器码验证

从图中可以看出,指令0xD0、0xD1、0xD2和0xD3在80x86架构CPU中不存在,指令0xD8-0xDF

在80x86架构CPU中代表了不同的指令。

机器码为0xEn的16个操作码,见表16。

表16 0xEn机器码及对应指令

机器码

E0

E1

E2

E3

E4

E5

E6

E7

E8

E9

EA

EB

EC

ED

EE

EF

验证结果见图15。

汇编指令

LOOPNE imm8

LOOPE imm8

LOOP imm8

JCXZ imm8

IN AL,imm8

IN AX,imm16

OUT AL,imm8

OUT AX,imm16

CALL imm16

JMP imm16

JMP imm32

JMP imm8

IN AL,DX

IN AX,DX

OUT AL,DX

OUT AX,DX

图15 0xEn机器码验证

从图中可以看出,我们验证的结果与理论值完全一致。

机器码为0xFn的16个操作码,见表17。

表17 0xFn机器码及对应指令

机器码

F0

F1

F2

F3

F4

F5

F6

F7

F8

F9

FA

FB

FC

FD

FE

FF

验证结果见图16。

汇编指令

LOCK

Not used

REPNE

REP

HLT

CMC

Table3 reg8

Table3 reg16

CLC

STC

CLI

STI

CLD

STD

Table4 reg8

Table4 reg16

图16 0xFn机器码验证

从图中可以看出,我们验证的结果除了80x86架构CPU中不一样的0xF6、0xF7、0xFE和0xFF

指令之外,其余指令与理论值完全一致。

参考文献:

[1] 机器语言.

[2] 80x86 Opcodes. /ece390/resources/

[3] 汇编指令机器码对应表.