111
1 第第第 80x86 第第第第第第第第

第二章 80x86 汇编语言程序设计

Embed Size (px)

DESCRIPTION

第二章 80x86 汇编语言程序设计. 操作码 操作数 ··· 操作数. 第一节 80x86 的寻址方式. 指令格式: 操作码 -- 应包含操作类型和操作数类型; 操作数 -- 可以是数据或用地址表示。 说明 — 操作数类型 (8/16/32 位、有 / 无符号等 ) 可在操作码或操作数字段中表示 (Intel 为后者 ). 存放操作数字段数据的部件: 寄存器、存储器、 I/O 接口,指令和堆栈。 - PowerPoint PPT Presentation

Citation preview

Page 1: 第二章   80x86 汇编语言程序设计

1

第二章 80x86 汇编语言程序设计

Page 2: 第二章   80x86 汇编语言程序设计

2

第一节 80x86 的寻址方式

指令格式: 操作码 -- 应包含操作类型和操作数类型; 操作数 -- 可以是数据或用地址表示。 说明—操作数类型 (8/16/32 位、有 / 无符号等 ) 可在操作

码或操作数字段中表示 (Intel 为后者 ) 存放操作数字段数据的部件: 寄存器、存储器、 I/O 接口,指令和堆栈。 说明 --① 寄存器、存储器、 I/O 接口均独立编址,分别构成

从 0 编址的寄存器空间、存储器空间、 I/O 空间;

② 指令中,堆栈不用地址表示,通过操作码表示。 寻址方式:产生操作数或其有效地址的方法。

操作码 操作数 ···  操作数

Page 3: 第二章   80x86 汇编语言程序设计

3

80x86 的寻址方式:寻址方式 数据所在地址

立即寻址 指令、寄存器寻址 寄存器、直接寻址 存储器、 I/O寄存器间接寻址 存储器、 I/O寄存器相对寻址 存储器基址变址寻址 存储器基址变址相对寻址 存储器比例变址寻址 存储器基址比例变址寻址 存储器相对基址比例变址寻址 存储器

说明:与比例有关的寻址方式在 80386 及以后 CPU 中才出现; I/O 空间和存储器的对应寻址方式表示形式不同。

Page 4: 第二章   80x86 汇编语言程序设计

4

数据所在地 寻址方式结果 备注指令 数据 译码时取得寄存器 物理地址 CPU 内部定位

存储器 有效地址PA= 有效地址与段寄存器的组合

I/O 物理地址 I/O 只有 16K 空间堆栈 不按地址访问,用存储器构建 存储器的有效地址 (EA) 与物理地址 (PA) :

有效地址—基于段的地址 ( 段内偏移地址 ) ; EA= 基址 +( 变址 * 比例因子 )+ 位移量 物理地址—基于存储器空间的地址。 实地址模式的 PA= 段地址 ×10H+EA

保护模式的 PA= 段地址的映像及变换 +EA回 9 页

Page 5: 第二章   80x86 汇编语言程序设计

5

存储器有效地址生成的相关约定:组成部分 16 位寻址 32 位寻址

基址寄存器 BX 、 BP 任何 32 位通用寄存器 ( 含ESP)

变址寄存器 SI 、 DI 除 ESP 外的任何 32 位通用寄存器

比例因子 无 1 、 2 、 4 、 8

位移量 0 、 8 、 16 位

0 、 8 、 16 、 32 位 存储器物理地址生成中的相关约定: a. 访存操作选择默认段寄存器规则— 取指操作和相对 IP 寻址的访存操作—代码段 CS , 堆栈操作和用 ESP/EBP 为基址的访存操作—堆栈段 SS , 串处理指令的目的串的访存操作—附加数据段 ES , 除堆栈和串处理的除目的串外的访存操作—数据段 DS 。

回下页 回 9页

回 13页

Page 6: 第二章   80x86 汇编语言程序设计

6

b. 指令中访问非默认段数据方法—段超越 可使用段超越前缀方式指明所访问数据所在的段。 段超越前缀种类:CS: 、 DS: 、 SS: 、 ES: 、 FS: 、 GS: 。 段超越示例: MOV AX,[10H] ; DS 段 10H 处的一个字的数

据 ;赋给 AX 寄存器 MOV AX,ES:[10H] ; ES 段 10H 处的一个字的

数据 ;赋给 AX 寄存器 不允许使用段超越前缀的情况: ( 1 )串处理指令的目的串必须用 ES 段; ( 2 )压栈 / 出栈指令的目的 / 源段必须用 SS 段; ( 3 )与程序中指令有关的操作必须用 CS 段。

转上页

Page 7: 第二章   80x86 汇编语言程序设计

7

1 、立即寻址 操作数存放在指令中 ( 以常量形式 ) 。

示例:⑴ MOV AH, -40 ; 0C0H(-40)→AH ⑵MOV AX, 5060H ; 50H→AH, 60H→AL ⑶MOV EAX, 12345678H ;12345678H→EAX 说明: 80x86 的操作数类型在地址码中表示

应用:适合于对常数的操作。

…操作码

D8H…

代码段…

操作码60H50H…

代码段AH

D8H

AX

50H 60H

示例⑴示意图 示例⑵示意图注:操作码中含目的操作数 ( 有时独立占一定信息位 )

低位在前低

Page 8: 第二章   80x86 汇编语言程序设计

8

2 、寄存器寻址 操作数存放在指令所指定寄存器号的寄存器中。

示例: MOV AH, BL ; (BL)→AH MOV DS, AX ; (AX)→DS MOV SI, AX ; (AX)→SI MOV ECX, EDX ; (EDX)→ECX

错误示例: MOV CS, AX ; CS 不能为 MOV 目的寄存器 MOV IP, BX ; IP 不能做 MOV 目的寄存器 MOV AX, CL ;目的与源 REG 类型 ( 位数 )不同 MOV BH, DX ;目的与源 REG 类型 ( 位数 )不同

应用:适合于对频繁使用的数据的操作。

Page 9: 第二章   80x86 汇编语言程序设计

9

3 、直接寻址 存储器操作数的有效地址直接存放在指令中, 即: EA= 指令地址码字段内容。

示例 1 : MOV AL, [100H] 若 (DS)=3000H ,

代码段

数据段

3100H

30100H

22H

11H…

则PA=3000H*10H+100H=30100H (AL)=11H示例 2 : MOV BL, ES:[100H] 若 (DS)=3000H , (ES)=2000H , 则 PA=2000H*10H+100H=20100H 。示例 3 : MOV AL,BUF 或 MOV AL,[BUF] 表示将从 BUF 开始的内容送 AL , BUF 以预先定义地址。说明:汇编语言允许用符号 ( 变量或标号 ) 地址代替数值地址。

转 4 页 转 5页

Page 10: 第二章   80x86 汇编语言程序设计

10

4 、寄存器间接寻址 存储器操作数的有效地址存放在指令所指定寄存器中,即: EA=( 寄存器 ) 。 寄存器的使用限制—

16 位寄存器

32 位寄存器 对应的段寄存器

BP EBP 、 ESP SS( 默认时不可以用其它 REG)

BX 、 SI、 DI

任意 32 位通用寄存器

DS( 默认时不可以用其它 REG)

说明:限制的目的是减少代码长度、提高执行速度

Page 11: 第二章   80x86 汇编语言程序设计

11

示例 1 : MOV AL, [BX] ;PA=(DS)*10H+(BX) MOV AX,CS:[SI];PA=(CS)*10H+(SI) MOV ECX, [EDX];PA=(EDS)*10H+(EDX) MOV AH, [BP] ;PA=(SS)*10H+(BP)

示例 2 : MOV AH, [BP] MOV BX, [SI] 设 (SS)=100H,(DS)=200H,(BP)=0B0H,(SI)=2AH 则第一条指令 PA=(SS)*10H+(BP) =1000H+0B0H=10B0H ; 第二条指令 PA=(DS)*10H+(SI) =2000H+2AH=202AH 。

应用:适合于对复杂数据结构的数据元素寻址。

Page 12: 第二章   80x86 汇编语言程序设计

12

5 、寄存器相对寻址(基址寻址或变址寻址) 操作数的有效地址为相对于指令所指定寄存器中地址的偏移地址,即: EA=( 寄存器 )+ 位移量。 寄存器的使用限制—与寄存器间接寻址方式相同。 示例 1 : MOV AX,300H[SI] (或 MOV AX,[SI+300H] ) 若 (DS)=3000H , (SI)=2000H 则 PA=(DS)*10H+(SI)+300H=32300H 示例 2 : MOV AX,BUF[SI] (或 MOV AX,[SI+BUF] )若 BUF=300H ,则与上例一致。 说明:汇编语言允许定义数据变量,所在存储器位置称为符号地址,与指令的地址标号不同 ( 所用段寄存器不同 ) 。应用:适合于动态再定位和对数组元素的访问。

Page 13: 第二章   80x86 汇编语言程序设计

13

6 、基址变址寻址 操作数的有效地址由指令所指定的基址 REG 与变址REG 的内容相加而成,即: EA=( 基址 REG)+( 变址 REG) 。 寄存器的使用限制—

转 5页

可使用寄存器的 对应的段寄存器基址REG

BX DSBP SS

变址REG

SI 、 DI

示例: MOV AX, [BX][DI] (亦可表示为 MOV AX,[BX+DI] ) 若 (DS)=2000H , (BX)=1000H ,(DI)=100H 则物理地址 =(DS)*10H+(BX)+(DI)=21100H应用:适合于对多维数组等复杂结构元素的访问。

Page 14: 第二章   80x86 汇编语言程序设计

14

7 、基址变址相对寻址 操作数的有效地址为相对于指令所指定的基址 REG

与变址 REG 的内容相加的地址的偏移地址, 即: EA=( 基址 REG)+( 变址 REG)+ 位移量。 寄存器的使用限制— 与基址变址寻址方式相同。 示例: MOV AX, 34H[BX][DI] (亦可表示为 MOV AX,34H[BX+DI] ) 若 (DS)=2000H , (BX)=1000H ,(DI)=100H 则 PA=(DS)*10H+(BX)+(DI)+34H=21134H

应用:适合于对多维数组等复杂结构元素的访问。

Page 15: 第二章   80x86 汇编语言程序设计

15

8 、比例变址寻址 操作数的有效地址为相对于指令所指定的变址 REG

内容和比例因子相乘的地址的偏移地址, 即: EA=( 变址 REG)* 比例因子 + 位移量。 寄存器的使用限制— 与基址变址寻址方式中变址 REG 限制相同。 示例: MOV AX, 200H[ESI*8] 若 (DS)=2000H , (ESI)=4 则 PA=(DS)*10H+(ESI)*4+200H=20220H

应用:适合于对结构数组等复杂结构元素的访问。

Page 16: 第二章   80x86 汇编语言程序设计

16

9 、基址比例变址寻址 操作数的有效地址为指令所指定的变址 REG 内容和比例因子相乘后与基址 REG 内容相加的地址, 即: EA=( 基址 REG)+( 变址 REG)* 比例因子。 寄存器的使用限制— 与基址变址寻址方式相同。 示例: MOV AX, [EBX+ESI*8]

应用:适合于对结构数组等复杂结构元素的访问。

Page 17: 第二章   80x86 汇编语言程序设计

17

10 、相对基址比例变址寻址 操作数的有效地址为相对于指令所指定的变址 REG

内容和比例因子相乘后与基址 REG 内容相加的偏移地址, 即: EA=( 基址 REG)+( 变址 REG)* 比例因子+ 位移量。 寄存器的使用限制— 与基址变址寻址方式相同。 示例: MOV AX, 200H[EBX+ESI*8]

应用:适合于对矩阵、结构数组等复杂结构元素的访问。

Page 18: 第二章   80x86 汇编语言程序设计

18

各种寻址方式比较寻址方式 物理地址 / 操作数

立即寻址 操作数 =( 地址码字段 )寄存器寻址 LA= 寄存器号,操作数 =( 寄存器 )直接寻址 LA=(SR)*10H+A

三个组成部分逐步增加

寄存器间接寻址 LA=(SR)*10H+(B 或I)

寄存器相对寻址 LA=(SR)*10H+(B 或I)+A

基址变址寻址 LA=(SR)*10H+(B)+(I)

基址变址相对寻址 LA=(SR)*10H+(B)+(I)+A

比例变址寻址 LA=(SR)*10H+ (I)*S+A

基址比例变址寻址 LA=(SR)*10H+(B)+(I)*S

相对基址比例变址寻址 LA=(SR)*10H+(B)+(I)*S+A

注:① (X)—X 的内容; SR— 段 REG ; A— 位移量; B—基址 REG I— 变址 REG ; S— 比例因子; LA— 线性地址 ② 采用 32 位寄存器时, B 、 I 基本可为任意通用寄存器

Page 19: 第二章   80x86 汇编语言程序设计

19

第二节 80x86 的指令系统 指令系统概况: 指令系统— { 指令 i} , 1≤i≤N ; 指令格式— 格式定义: [ 前缀 ] 操作码 {[ 操作数 ][, 操作数 ]}

操作数类型:整数 ( 长度 / 符号 ) 、浮点数、指针、位域数、串数据、 SIMD 数据、 BCD/ 压缩BCD 数据 特性:定长 / 变长、寻址方式种类及其表示 指令表示形式: 二进制格式—通过二进制编码串描述具体指令; ☆汇编语言格式—通过助记符形式描述具体指令。

Page 20: 第二章   80x86 汇编语言程序设计

20

80x86 指令的汇编语言一般格式: [ 标号 :] 指令助记符 [ 目的操作数 ][, 源操作数 ][; 注释 ]

说明 --① 标号又称地址标号,表示指令的地址 ( 符号地址 )

②80x86 目的操作数在前,源操作数在后 ③操作数可用立即数、地址码形式表示 80x86 指令系统指令类型: ⑴ 数据传送类指令 ⑷控制转移类指令 ⑵算术运算类指令 ⑸串操作类指令 ⑶逻辑运算与移位类指令 ⑹处理器控制类指令

Page 21: 第二章   80x86 汇编语言程序设计

21

一、数据传送类指令 包含通用数据传送、地址传送、标志传送、输入输出、类型转换 5 种子类型的指令。1 、通用数据传送指令 MOV(move) 传送 MOVSX(move with sigh-extend) 带符号扩展传送 MOVZX(move with zero-extend) 带零扩展传送 PUSH(push onto the stack) 进栈 POP(pop from the stack) 出栈 PUSHA/PUSHAD(push all registers) 所有寄存器进栈 POPA/POPAD(pop all registers) 所有寄存器出栈 XCHG(exchange) 交换 XLAT(translate) 换码 (查表 )

MOVSX 、 MOVSZ 、 PUSHA/PUSHAD 、 POPA/POPAD 非 8086 指令

Page 22: 第二章   80x86 汇编语言程序设计

22

( 1 ) MOV 传送指令 格式: MOV DST , SRC

操作: DST←(SRC)

即把源操作数的内容送入目的操作数 说明: 1 ) SRC 、 DST 操作数允许类型见下图 2 ) SRC 、 DST 数据类型应相同 3 )可进行 8/16/32 位数据传送,由操作数类型确定 4 )该指令不影响任何状态标志位

回 24页

回 25页

回段 REG 指定

存储器

段寄存器DS ES SS

CS

立即数

通用寄存器

AX BX CX DX

BP SP SI DI

指令指针寄存器 IP

标志寄存器FLAG

Page 23: 第二章   80x86 汇编语言程序设计

23

MOV 指令例 1 : MOV AL,BL ;寄存器间传送 ( 数据长度一致 ) MOV BP,SI

MOV EAX,[EBX+ECX*4] ;存储器→寄存器 ( 数据长度 MOV AX,ARRAY[SI] ; 由 REG决定 ) MOV AX,0B00H ;立即数→寄存器 ( 数据长度 MOV CL,10000000B ; 由 REG决定 )

MOV VALUE, 100H ;立即数→存储器 ( 数据长度 MOV ES:[BX], 4BH ; 由 VALUE决定 )

MOV [BX], CX ;寄存器→存储器 MOV BUFF[BP][DI], AX

MOV 指令例 2 : MOV AX,

1000H[SI] 设 (DS)=3000H,(SI)=2000H

33000H

6000H 23H0BH

0BH34H… 则 PA=33000H,(AX)=340BH

Page 24: 第二章   80x86 汇编语言程序设计

24

注意事项:(☆理解 P22 示意图) ①两个操作数长度必须一致 MOV AL, BX ;不合法,数据类型不一致 MOV AX, 0B4H ;合法,执行后 (AX)=0FFB4H

;源为立即数,长度小于目的寄存器 ;位数时,高位按符号位方式扩展 MOV AX , [100H] ;合法,存储器操作数长度由寄存器 MOV [SI] , AL ;操作数长度决定 MOV [DI] , 1234H ; [DI] 所指存储单元未定义为字类 ;型时不合法,可通过寄存器中转 MOV BYTE PTR[SI] , 40 ;合法,将类型通知汇编程序 转 22 页

Page 25: 第二章   80x86 汇编语言程序设计

25

② 不允许两个操作数均是存储器操作数 MOV X, Y ;不合法 可通过寄存器中转传送: MOV AX, Y MOV X, AX

③不允许两个操作数均为段寄存器 不允许用立即数为段寄存器赋值 ④不允许 CS 、立即数做目的操作数 MOV CS, AX ;不合法 MOV 100H, AX ;不合法

⑤不允许 IP 做操作数 ⑥表示目的存储器操作数数据类型的方法: MOV BYTE PTR[SI], 40 ;指定数据类型 MOV VALUE, 40 ;通过伪指令定义变量类型

转 22页

Page 26: 第二章   80x86 汇编语言程序设计

26

( 2 ) MOVSX/MOVZX 带符号 /零扩展传送指令 格式: MOVSX DST , SRC

MOVZX DST , SRC

操作: DST← 符号扩展 (SRC)

DST←零扩展 (SRC)

即把源操作数的内容扩展后送入目的操作数 说明: 1 ) SRC 可为寄存器、存储器操作数,不可为立即数 2 ) DST 只可为寄存器操作数 3 )可进行 8/16 位数据传送, SRC 位数应小于 DST

位数 4 )该指令不影响任何状态标志位

Page 27: 第二章   80x86 汇编语言程序设计

27

MOVSX 指令示例: MOVSX EAX,CL

设 (CL)=0ABH , 执行结果 (EAX)=0FFFFFFABH ;负号扩展 若 (CL)=57H , 执行结果 (EAX)=000000057H ;正号扩展

MOVZX 指令示例: MOVZX EAX,DATA

设 (DATA)=87ADH , 执行结果 (EAX)=000087ADH ;零扩展

Page 28: 第二章   80x86 汇编语言程序设计

28

( 3 ) PUSH 压栈指令 格式: PUSH SRC

16 位操作: SP←(SP)-2

((SP)+1,(SP))←(SRC) 32 位操作: ESP←(ESP)-4 ((ESP)+3,(ESP)+2,(ESP)+1,(ESP))←(SRC)

说明: 1 ) SRC 可为寄存器、存储器操作数 8086 后 SRC 可为立即数 2 ) SRC 必须为 16/32 位,立即数 SRC 可自动扩展 3 )该指令不影响任何状态标志位

Page 29: 第二章   80x86 汇编语言程序设计

29

示例 2 : PUSH AX 设 (AX)=2135H

低地址

SP 2500H

执行前 低地址

SP

2500H

执行后

21H35H

24FFH24FEH

进栈方向

示例 1 : PUSH AX PUSH DAT[BX][SI] ; 注意寻址方式中REG

PUSH 1234H PUSH 87654321H

Page 30: 第二章   80x86 汇编语言程序设计

30

( 4 ) POP 出栈指令 格式: POP DST

16 位操作: DST←((SP)+1,(SP))

SP←(SP)+2 32 位操作: DST←((ESP)+3,(ESP)+2,(ESP)+1,(ESP)) ESP←(ESP)+4

说明: 1 ) DST 可为寄存器、存储器操作数 2 ) DST 必须为 16/32 位 3 )该指令不影响任何状态标志位

Page 31: 第二章   80x86 汇编语言程序设计

31

示例 1 : POP AX POP DAT[BX][SI]

POP DX

示例 2 : POP AX

低地址

SP

2502H

执行前

6FH43H

2501H2500H

28H33H

2503HAX

21 3D 出栈方向

低地址

SP 2502H

执行后

6FH43H

2501H2500H

28H33H

2503H

AX

6F 43

Page 32: 第二章   80x86 汇编语言程序设计

32

( 5 ) PUSHA/PUSHAD 所有寄存器压栈指令 格式: PUSHA

PUSHAD

16 位操作:① 16 位通用寄存器AX 、 CX 、 DX 、 BX 、 SP 、 BP 、 SI 、 DI 的内容按顺序压栈 ②SP←(SP)-16

32 位操作:① 32 位通用寄存器EAX 、 ECX 、 EDX 、 EBX 、 ESP 、 EBP 、 ESI

、 EDI 的内容按顺序压栈 ②ESP←(ESP)-32

说明: 1 )压栈时的 SP 和 ESP 的内容为指令执行前的内容 2 )该指令不影响任何状态标志位

Page 33: 第二章   80x86 汇编语言程序设计

33

( 6 ) POPA/POPAD 所有寄存器出栈指令 格式: POPA

POPAD

16 位操作:① 16 位通用寄存器 DI 、 SI 、 BP 、SP 、 BX 、 DX 、 CX 、 AX 的内容按顺序出栈 ②SP←(SP)+16

32 位操作:① 32 位通用寄存器EDI 、 ESI 、 EBP 、 ESP 、 EBX 、 EDX 、 ECX

、 EAX 的内容按顺序出栈 ②ESP←(ESP)+32

说明: 1 )指令执行后 SP 或 ESP 的内容与栈中弹出的SP 或 ESP 的内容无关 2 )该指令不影响任何状态标志位

Page 34: 第二章   80x86 汇编语言程序设计

34

( 7 ) XCHG 交换指令 格式: XCHG OPER1 , OPER2

操作: (OPER1)←→(OPER2)

说明: 1 ) OPER1 和 OPER2 可为寄存器、存储器操作数,但绝不允许为段寄存器,且不允许同时为存储器操作数 2 ) OPER1 和 OPER2 数据长度必须相同 3 )该指令不影响任何状态标志位

示例: XCHG EAX, EBX ;寄存器间交换 XCHG BX, [BP+DI] ;寄存器与存储器间交换 XCHG DS, EX ;不合法 XCHG [SI], [DI] ;不合法

Page 35: 第二章   80x86 汇编语言程序设计

35

( 8 ) XLAT 查表指令 格式: XLAT TABLE 或 XLAT

操作: AL←((BX)+(AL)) 或 AL←((EBX)+(AL))

说明: 1 )操作前必须先将表首址 (TABLE) 送给 BX ,再将目标项与距表头的偏移量送给 AL

2 )该指令不影响任何状态标志位

示例: LEA BX,TABLE ;表首址给BX

MOV AL,4 ;偏移量给 AL

XLAT

43H42H

+1+2+3+4+5

TABLE

45H44H

AL

44H

41H40H

Page 36: 第二章   80x86 汇编语言程序设计

36

2 、地址传送指令 LEA (load effective address) 有效地址送寄存器 LDS (load DS with pointer) 地址指针送寄存器和DS LES (load ES with pointer) 地址指针送寄存器和ES LFS (load FS with pointer) 地址指针送寄存器和FS LGS (load GS with pointer) 地址指针送寄存器和GS LSS (load SS with pointer) 地址指针送寄存器和SS

LFS 、 LGS 、 LSS 非 8086 指令。

Page 37: 第二章   80x86 汇编语言程序设计

37

( 1 ) LEA 取有效地址指令 格式: LEA DST, SRC

操作: DST←SRC 的有效地址 EA

说明: 1 ) SRC 必须是存储器操作数 2 ) DST 必须是 16 位或 32 位通用寄存器 3 )该指令不影响任何状态标志位

示例 1 : LEA SI,[BX] 设 (DS)=2000H,(BX)=1234H 执行后

21234H21235H 41H

40H1234HSI

1234HBX

示例 2 : LEA DI,BUFF ;将 BUFF 的有效 ;地址送 DI ,而 ;非将 BUFF 的值 ;送 DI

Page 38: 第二章   80x86 汇编语言程序设计

38

( 2 ) LDS 装载数据段地址指针指令 格式: LDS DST,SRC

操作: DST←(SRC) 或 DST←(SRC+2,SRC)

DS←(SRC+2) DS←(SRC+4)

说明: 1 ) SRC 必须是存储器操作数 2 ) DST 必须是 16 位或 32 位通用寄存器 3 )该指令不影响任何状态标志位 LES 、 LFS 、 LGS 、 LSS 指令: 格式 -- 同 LDS ,仅操作助记符不同 操作—同 LDS ,仅目标段寄存器不同

Page 39: 第二章   80x86 汇编语言程序设计

39

LDS 指令示例 1 : LDS DI,[BX]

设 (DS)=2000H,(BX)=1000H

21000H21001H21002H21003H

41H40H1234HDI

2000HDS

执行前

43H42H

4140H DI

4342H DS

执行后

LDS 指令示例 2 : LEA SI,BUFF

  ( 与 LEA 比较 ) LDS DI,BUFF

设 (DS)=2000H,EABUFF=1000H

21000H21001H21002H21003H

41H40H

43H42H

执行后 (SI)=1000H (DI)=4140H ,(DS)=4342H

Page 40: 第二章   80x86 汇编语言程序设计

40

3 、标记传送指令 LAHF(load AH with flags) 取标志到 AH SAHF(store AH into flags) 从 AH 存标志

PUSHF/PUSHFD(push the flags or eflags) 标志进栈 POPF/POPFD(pop the flags or eflags) 标志出栈

PUSHFD 、 POPFD 非 8086 指令。

Page 41: 第二章   80x86 汇编语言程序设计

41

( 2 ) SAHF 存 FLAG 标志寄存器指令 格式: SAHF

操作: FLAG7~0←(AH)

将 AH 的内容存到 FLAG 标志寄存器的低 8 位中。 说明:该指令改变 SF 、 ZF 、 AF 、 PF 、 CF 标志。

( 1 ) LAHF 取 FLAG 标志寄存器指令 格式: LAHF

操作: AH←(FLAG)7~0

将 FLAG 标志寄存器的低 8 位送到 AH 中。 说明:该指令不影响标志状态位。

Page 42: 第二章   80x86 汇编语言程序设计

42

( 4 ) POPF/POPFD FLAG 标志寄存器出栈指令 格式: POPF 和 POPFD

操作: FLAG←((SP)+1,(SP))

SP←(SP)+2 和 EFLAG←((ESP)+3,(ESP)+2,(ESP)+1,(ESP)) ESP←(ESP)+4

( 3 ) PUSHF/PUSHFD FLAG 标志寄存器进栈指令 格式: PUSHF 和 PUSHFD

操作: SP←(SP)-2

((SP)+1,(SP))←(FLAG) 和 ESP←(ESP)-4 ((ESP)+3,(ESP)+2,(ESP)+1,(ESP)) ←(EFLAG) AND 0FCFFFFH

Page 43: 第二章   80x86 汇编语言程序设计

43

4 、输入输出指令

IN(input) 从 I/O 接口空间读数据 OUT(output) 向 I/O 接口空间写数据

I/O 接口空间大小: 16根地址线、每个地址对应 1 个 8 位空间; 即 64K 个 8 位空间 =32K 个 16 位空间 =16K 个32 位空间。 I/O 接口空间内数据的传输方式: 支持 8 位、 16 位、 32 位数据传输; 16 位和 32 位传输时,地址需按整数边界对齐。 8086 不支持 32 位数据传输。

Page 44: 第二章   80x86 汇编语言程序设计

44

I/O 空间的寻址方式: 只支持直接寻址、 ( 寄存器 ) 间接寻址两种。

说明— ① 直接寻址只支持 8 位的地址 ( 高 8 位为 0) ; ②( 寄存器 ) 间接寻址只能使用 DX 寄存器 (16

位 ) ; ③寻址方式格式与存储器操作数的格式不同。存储器操作数 I/O 操作数

直接寻址 [2000H] 20H

( 寄存器 ) 间接寻址

[DX] DX

回下页 回 46 页 回 I/O 接口技术

Page 45: 第二章   80x86 汇编语言程序设计

45

( 1 ) IN 从 I/O 接口输入数据指令 格式: IN AL, n IN AX, n 直接寻址, n 是地址常量 IN EAX, n IN AL, DX IN AX, DX ( 寄存器 ) 间接寻址 IN EAX, DX

操作: AL←(n) 或 (DX) AX←(n+1,n) 或 ((DX)+1,(DX)) EAX←(n+3,…,n) 或 ((DX)+3,…,(DX))

说明:①目的操作数只能是 AL/AX/EAX 寄存器; ② 源操作数要求参见寻址方式说明 ( 上页 ) ; ③读入数据长度取决于目的寄存器的位数。

转上页

Page 46: 第二章   80x86 汇编语言程序设计

46

( 2 ) OUT 向 I/O 接口输出数据指令 格式: OUT n, AL OUT n, AX 直接寻址, n 是地址常量 OUT n, EAX OUT DX, AL OUT DX, AX ( 寄存器 ) 间接寻址 OUT DX, EAX

操作: n 或 (DX)←(AL) (n+1,n) 或 ((DX)+1,(DX))←(AX) (n+3,…,n) 或 ((DX)+3,…,(DX))←(EAX)

说明:①源操作数只能是 AL/AX/EAX 寄存器; ② 目的操作数要求参见寻址方式说明; ③写出数据长度取决于源寄存器的位数。

转 44 页

Page 47: 第二章   80x86 汇编语言程序设计

47

IN 指令示例: IN AL, 20H ;从 20H端口读入字节数据→ AL

IN AX, 48H ;从 48H端口读入字数据→ AX

MOV DX, 3FCH

IN EAX, DX ;从 03FCH端口读入双字数据→EAX OUT 指令示例: OUT 32H, AX ;传送字数据到 32H端口 MOV DX, 400H

MOV AL, 86H

OUT DX, AL ;传送字节数据到DX 指定的端口 OUT DX , 86H ;不合法,立即数可扩展(8/16?)

Page 48: 第二章   80x86 汇编语言程序设计

48

5 、类型转换指令 CBW(convert byte to word) 字节转换为字 CWD/CWDE(convert word to double word) 字转换为双字 CDQ(convert double to quad) 双字转换为 4字 BSWAP(byte swap) 字节交换 CWDE 、 CDQ 、 BSWAP 非 8086 指令。( 1 ) CBW 字节转换为字指令 格式: CBW

操作:扩展 AL 中符号位至 AH 中, 将 8 位数扩展成等效的 16 位数。

Page 49: 第二章   80x86 汇编语言程序设计

49

( 2 ) CWD/CWDE 字转换为双字指令 格式: CWD

操作:扩展 AX 中符号位至DX 中,形成等效的 32

位数。 格式: CWDE

操作:扩展 AX 中符号位至 EAX 中 , 形成等效的 32

位数。 说明:用于有符号数相除前,形成双倍长度被除数。( 3 ) CDQ 双字转换为 4 字指令 格式: CDQ

操作:扩展 EAX 中符号位至 EDX 中,形成EDX:EAX 形式的 4 字数据。

Page 50: 第二章   80x86 汇编语言程序设计

50

数据传送指令小结1 、数据传送指令不影响标志位 ( 除 SAHF 、 POPF)

2 、除 XCHG 指令外,都是从源到目的的单向传送3 、注意 MOV 指令与 LEA 指令的区别 MOV传送的是地址对应的内容, LEA传送的是 EA

4 、 80286 后才允许 PUSH 指令使用立即数寻址方式5 、与存储器操作数有关的寄存器问题 MEM 操作数的寻址方式中只能用基址、变址寄存器6 、段寄存器问题 只能在 MOV 、 PUSH 、 POP 等指令中作为操作数出现, CS 寄存器比其他段寄存器有更多限制。7 、最常用指令: MOV 、 IN/OUT 、 LEA 、 PUSH/

POP 、 XCHG 、 CBW

Page 51: 第二章   80x86 汇编语言程序设计

51

二、算术运算类指令 包含加法、减法、乘法、除法、十进制调整运算 5

种子类型指令。

算术运算指令可对 4 种类型操作数运算: ⑴ 无符号二进数 ⑵ 有符号二进数 ⑶非压缩十进数 一个字节存放一位十进数的 BCD 码,高 4 位为零。 ⑷压缩十进数 一个字节存放两位十进数的 BCD 码。

Page 52: 第二章   80x86 汇编语言程序设计

52

0 、算术运算中的相关标志及处理( 1 ) 8086 标志寄存器 FLAG 的标志位

OF DF IF TF SF ZF AF PF CFD15 D11 D10 D9 D8 D7 D6 D4 D2 D0

符号 名称 值为‘ 1’ 的条件CF 进位标志 加 / 减法时产生进位 /借位OF 溢出标志 运算结果超出有符号整数能表示的范围ZF 零标志 运算结果为 0 时SF 符号标志 运算结果的最高位为“ 1” 时AF 辅助进位标志 运算时半字节( b3 )产生进位 /借位PF 奇偶标志 操作结果低 8 位为” 1” 的位数为偶数

时DF 方向标志 串操作中地址指针向低地址方向移动IF 中断允许标志 允许 CPU响应可屏蔽中断请求时TF 跟踪标志 CPU 处于单步执行的工作方式回下页 回 103

Page 53: 第二章   80x86 汇编语言程序设计

53

( 2 )算术运算与 FLAG 中标志位的关系 FLAG 标志位的补充说明: ①CF 的含义是无符号数运算的溢出标志(CF=Cn) ; ②ZF 表示运算结果是否为零 ( 含最高位 ) ,即无符号数运算结果是否为零。 8086运算器 ALU 对加、减法运算的处理方式: ALU 按无符号数进行运算,求得结果,设置 CF 、ZF 、 AF 和 PF ; ALU 按有符号数方式设置 SF 和 OF(OF=Cn-1 +

Cn) 。 说明: Cn 和 Cn-1 分别为最高位和次高位进位信号,见组成原理 P51 。

8086运算器 ALU 对乘、除法运算的处理方式: 通过有 / 无符号运算指令可进行相应运算。转上页 回下页

Page 54: 第二章   80x86 汇编语言程序设计

54

8000H

+8000

H

0000H

C000H

+C000

H

8000H

4008H

+4008H

8010H

0808H

+C000H

C808H

CF 1 1 0 0PF 1 1 0 0ZF 1 0 0 0SF 0 1 1 1OF 1 0 1 0

加法运算及 FLAG 标志位关系例题:

汇编语言程序员编程时的处理方法: 对有 / 无符号数 --手工用补码 /原码表示; 对溢出问题—无符号运算时应关心 CF , 有符号运算时应关心OF 。

转上页

Page 55: 第二章   80x86 汇编语言程序设计

55

1 、加法指令 有 ADD 、 ADC 、 INC 、 XADD四种, XADD 非8086 指令。( 1 ) ADD 加法指令 格式: ADD DST , SRC

操作: DST←(DST)+(SRC)

说明: 1 ) DST 、 SRC 操作数允许类型见下图 (5 种组合 )

2 )可进行无符号和有符号的 8 位或 16 位运算 3 )两个操作数类型应一致 4 )运算结果对 CF 、 SF 、 OF 、 PF 、 ZF 、 AF 均有影响

存储器

立即数 通用寄存器AX BX CX DXBP SP SI DI

SRC

DST

DST←(DST)+(SRC)

Page 56: 第二章   80x86 汇编语言程序设计

56

ADD 指令示例 1 : ADD DX , BX

设 (DX)=4652H, (BX)=0F0F0H

4652H+ F0F0H 1 3742H

0100 0110 0101 0010+ 1111 0000 1111 00001 0011 0111 0100 0010

进位 进位

执行后: (DX)=3742H

标志位 ZF=0 结果不为 0 SF=0 结果为正 CF=1 有进位 OF=0 不溢出 (C16 + C15=0)

Page 57: 第二章   80x86 汇编语言程序设计

57

ADD 指令示例 2 : ADD WORD PTR[BX], 8F76H

设 (DS)=2000H, (BX)=1000H

21000H21001H A9H

88H

执行前 A988H + 8F76H 1 38FEH

进位

21000H21001H 38H

FEH

执行后 标志位 ZF=0 结果不为 0 SF=0 结果为正 CF=1 有进位 OF=1 溢出 (C16 + C15=1)

Page 58: 第二章   80x86 汇编语言程序设计

58

( 2 ) ADC 带进位加法指令 格式: ADC DST , SRC

操作: DST←(DST)+(SRC)+(CF)

说明:所有限制与 ADD 指令相同。 ADC 指令示例: --双字加法 设目的操作数在 DX( 高位字 ) 和 AX 、源操作数在 BX( 高位字 ) 和 CX 中, (DX)=0418H , (AX)=0F365H ,(BX)=1005H , (CX)=0E024H

DX

BX+

DX

AX

CX+

AX

CF

指令序列为: ADD AX , CX ;低位字相加 ADC DX , BX ;高位字相加ADD 指令结果 :

(AX)=0D389H , CF=1

ADC 指令结果 :(DX)=141EH

Page 59: 第二章   80x86 汇编语言程序设计

59

( 3 ) INC 加 1 指令 格式: INC DST

操作: DST←(DST)+1 说明: 1 ) DST 只可为 ( 通用 ) 寄存器、存储器操作数 2 )运算结果影响 SF 、 OF 、 PF 、 ZF 、 AF ,不影响 CF 示例 1 : INC SI INC WORD PTR[BX] INC CL

示例 2 : (左右两边结果相同) LEA BX, ARRAY ; MOV BX , 0 MOV AL, [BX] ; MOV AL , ARRAY[BX] …… ;…… INC BX ; INC BX

Page 60: 第二章   80x86 汇编语言程序设计

60

2 、减法指令 有SUB 、 SBB 、 DEC 、 NEG 、 CMP 、 CMPXCH

G 、 CMPXCHG8B 7

种, CMPXCHG 、 CMPXCHG8B 非 8086 指令。( 1 ) SUB 减法指令 格式: SUB DST , SRC

操作: DST←(DST)-(SRC)

说明:所有限制与 ADD 指令相同。 SUB 指令示例: SUB BX , CX

设 (BX)=9543H, (CX)=28A7H

执行后 :(BX)=6C9CH

标志位 CF=0 、 OF=1 、 ZF=0 、 SF=0

Page 61: 第二章   80x86 汇编语言程序设计

61

( 2 ) SBB 带借位减法指令 格式: SBB DST , SRC

操作: DST←(DST)-(SRC)-(CF)

说明:所有限制与 ADC 指令相同。( 3 ) DEC 减 1 指令 格式: DEC DST

操作: DST←(DST)-1

说明:所有限制与 INC 指令相同。( 4 ) NEG 取补指令 格式: NEG DST

操作: DST←-(DST) ,或 DST←0-(DST)

说明:所有限制与 SUB 指令相同。

Page 62: 第二章   80x86 汇编语言程序设计

62

( 5 ) CMP 比较指令 格式: CMP OPRD1 , OPRD2

操作: (OPRD1)-(OPRD2) ,结果不送给任何操作数 说明: 1 )该指令无目的操作数,即不改变任何操作数值; 2 )所有限制和对标志位的影响均与 SUB 指令相同; 3 )该指令仅改变 FLAG 标志位,常用作转移条件。 应用: ⑴ 比较两数是否相等,根据 ZF判断 若 ZF=1 ,则两数相等;否则不等

⑵ 比较两数大小时,需区分是有 / 无符号数比较 无符号数—若 CF=0 ,则 DST≥SRC ;否则 DST< SRC

有符号数—若 SF=OF ,则 DST≥SRC ;否则 DST<SRC

( 通过 DST 和 SRC 的枚举可证明 )回 78 页

Page 63: 第二章   80x86 汇编语言程序设计

63

3 、乘法指令( 1 ) MUL 无符号乘法指令 格式: MUL SRC

操作:字节相乘 AX←(AL)×(SRC)BYTE

单字相乘 DX:AX←(AX)×(SRC)WORD

说明: 1 ) SRC 可为通用寄存器和存储器操作数, 目的操作数只能为 AX 或 DX:AX ; 2 )结果仅影响 FLAG 的 CF 和 OF 。 字节或字相乘后 (AH)≠0 或 (DX)≠0 ,则CF=OF=1 ; 否则, CF=OF=0( 2 ) IMUL 带符号乘法指令 格式: IMUL SRC

操作和说明:与 MUL 指令相同。

Page 64: 第二章   80x86 汇编语言程序设计

64

MUL 和 IMUL 指令示例: MUL BL

设(AL)=0B4H=180

(BL)=11H=17 1011 0100 × 0001 0001 1011 0100 1011 0100 1011 1111 0100

(AX)=0BF4H=3060

IMUL BL

设 (AL)=0B4H=-

76

(BL)=11H=17

-76 补 =4CH 0100 1100 × 0001 0001 0100 1100 0100 1100 0101 0000 1100

(AX)=(-050C) 补 =FAF4H= -1292

Page 65: 第二章   80x86 汇编语言程序设计

65

4 、除法指令( 1 ) DIV 无符号除法指令 格式: DIV SRC

操作:字节除法 AL(商 ) 、 AH(余数 )←(AX)÷(SRC)BYTE

字除法 AX(商 ) 、 DX(余数 )←(DX)

(AX)÷(SRC)WORD

说明: 1 ) SRC 可为通用寄存器和存储器操作数, 目的操作数只能为 AX 或 DX:AX ; 2 )结果仅影响 FLAG 的 OF 。 当商大于商寄存器最大范围时, OF=1 ;否则 OF=0( 2 ) IDIV 带符号除法指令 格式: IDIV SRC

操作和说明:与 DIV 指令相同。

Page 66: 第二章   80x86 汇编语言程序设计

66

算术运算指令综合例题: 计算 (V-(X*Y+Z))/X ,其中 X,Y,Z,V 均为 16 位有符号数,要求商存入 AX ,余数存入DX MOV AX, X IMUL Y ; DX:AX←X*Y MOV CX, AX MOV BX, DX ;积存于 BX:CX MOV AX, Z CWD ; Z扩展→DX : AX ADD CX, AX ; X*Y+Z ADC BX, DX MOV AX, V CWD ; V扩展→DX : AX SUB AX, CX ;相减 SBB DX, BX IDIV X ;除以 X

Page 67: 第二章   80x86 汇编语言程序设计

67

5 、十进制调整指令 目的:将用二进制 ALU运算的十进制数的结果调整为十进制数。 种类: 对非压缩 BCD 码有:AAA 、 AAS 、 AAM 、 AAD 指令; 对压缩 BCD 码有: DAA 、 DAS 指令。( 1 ) AAA 非压缩 BCD 码加调整指令 格式: AAA

操作:对两个非压缩 BCD 码数相加的结果进行调整。 说明: 1 )隐含的源、目的操作数分别是 AL 和 AX ; 2 )该指令仅对 AF 和 CF 标志有影响; 3 )该指令一般紧跟在 ADD 指令之后。

Page 68: 第二章   80x86 汇编语言程序设计

68

AAA 指令调整算法: 如果 (AL&0FH)>9 或 (AF)=1 // 和 >10 或和 >16 则   AL←(AL)+6 AH←(AH)+1 // 非压缩 BCD 码进位到 AH 中 AF←1 // 表示个位和有进位 AL←(AL)&0FH //整理成非压缩 BCD 码 CF←(AF)

AAA 指令示例: MOV AL , 9H MOV BL , 4H ADD AL , BL ;和 =0DH AAA ;调整后 (AH)=01H,(AL)=03H,CF=AF=1 思考:为何调整时用 AH←(AH)+1 ,而非AH←1?

Page 69: 第二章   80x86 汇编语言程序设计

69

( 2 ) AAS 非压缩 BCD 码减调整指令 格式: AAS

操作:对两个非压缩 BCD 码数相减的结果进行调整。 说明: 1 )隐含的源、目的操作数分别是 AL 和 AX ; 2 )该指令仅对 AF 和 CF 标志有影响; 3 )该指令一般紧跟在 SUB 指令之后。 AAS 指令调整算法: 如果 (AL&0FH)>9 或(AF)=1 则   AL←(AL)-6 AH←(AH)-1 AF←1 AL←(AL)&0FH CF←(AF)

AAS 指令示例: MOV AX , 0206H MOV BL , 07H SUB AL , BL ;(AL)=FFH AAS ;调整后 (AH)=01H, ; (AL)=09H, CF=AF=1

Page 70: 第二章   80x86 汇编语言程序设计

70

( 3 ) AAM 非压缩 BCD 码乘调整指令 格式: AAM

操作:对两个非压缩 BCD 码数相乘的结果进行调整。 说明: 1 )隐含的源、目的操作数分别是 AL 和 AX ; 2 )该指令仅对 SF 、 ZF 和 PF 标志有影响; 3 )该指令一般紧跟在 MUL 指令之后。 AAM 指令调整算法: 将 AL 除以 0AH ,商放到 AH 中,余数放到 AL

中; 根据调整后的 AL 设置 SF 、 ZF 、 PF 。

Page 71: 第二章   80x86 汇编语言程序设计

71

( 4 ) AAD 非压缩 BCD 码除调整指令 格式: AAD

操作:将非压缩 BCD 码数调整为二进制数。 说明: 1 )隐含的源、目的操作数均是 AX ; 2 )该指令仅对 SF 、 ZF 和 PF 标志有影响; 3 )该指令应放在 DIV 指令之前。

AAD 指令调整算法: AL←10×AH+AL

AH←0

根据调整后的 AL 设置 SF 、 ZF 、 PF

应用:可用于将非压缩 BCD 码数转换成二进制数。

Page 72: 第二章   80x86 汇编语言程序设计

72

( 5 ) DAA 压缩 BCD 码加调整指令 格式: DAA

操作:对两个压缩 BCD 码数相加的结果进行调整。 说明: 1 )隐含的源、目的操作数均是 AL ; 2 )该指令对 AF 、 CF 、 PF 、 SF 和 ZF 标志有影响; 3 )该指令一般紧跟在 ADD 指令之后。 DAA 指令调整算法: 如果 (AL&0FH)>9 或 (AF)=1 // 个位和 >10 或个位和 >16 则   AL←(AL)+6 AF←1 // 表示个位和有进位 如果 AL>9FH 或 (CF)=1 //十位和 >10 或十位和>16 则   AL←(AL)+60H // 第一版教材 P69 有错误! CF←1 // 表示十位和有进位

Page 73: 第二章   80x86 汇编语言程序设计

73

( 6 ) DAS 压缩 BCD 码减调整指令 格式: DAS

操作:对两个压缩 BCD 码数相减的结果进行调整。 说明: 1 )隐含的源、目的操作数均是 AL ; 2 )该指令对 AF 、 CF 、 PF 、 SF 和 ZF 标志有影响; 3 )该指令一般紧跟在 SUB 指令之后。 DAS 指令调整算法: 如果 (AL&0FH)>9 或 (AF)=1 // 个位差<0 或有借位 则   AL←(AL)-6 AF←1 // 表示个位差有借位 如果 AL>9FH 或 (CF)=1 //十位差<0 或有借位 则   AL←(AL)-60H CF←1 // 表示十位差有借位

Page 74: 第二章   80x86 汇编语言程序设计

74

DAA 、 DAS 指令示例: A~C 处是 4 位压缩 BCD 码数,计算 A-B+C ,存入 C

A

B

C

76H35H

12H46H

64H02H

MOV AL , A SUB AL , B ;计算 A-B 的低两位 DAS ;调整低两位差 (36H,CF=1) MOV CL , AL MOV AL , A+1 SBB AL , B+1 ;计算 A-B 的高两位 DAS ;调整高两位差 (10H,CF=0) MOV CH , AL MOV AL , C ADD AL , CL ;计算 (A-B) 的低两位与 C 的低两位的和 DAA ;调整底两位和 (00H,CF=1) MOV C , AL MOV AL , C+1 ADC AL , CH ;计算 (A-B) 的高两位与 C 的高两位的和 DAA ;调整高两位和 (13H,CF=0) MOV C+1 , AL

Page 75: 第二章   80x86 汇编语言程序设计

75

三、逻辑运算和移位类指令1 、逻辑运算类指令 有逻辑非、逻辑与、逻辑或、逻辑异或、测试指令。( 1 ) NOT 逻辑非指令 格式: NOT OPRD

操作: OPRD←(OPRD)

说明: 1 ) OPRD 可为通用寄存器、存储器操作数; 2 )可进行 8 位或 16 位运算,根据 OPRD 数据类型决定; 3 )该指令不影响 FLAG 的标志位。 示例: MOV AL , 52H ; 0101 0010

NOT AL ;执行后 1010 1101

Page 76: 第二章   80x86 汇编语言程序设计

76

( 2 ) AND/OR/XOR 逻辑与 / 或 /异或指令 格式: AND DST , SRC

OR DST , SRC

XOR DST , SRC

操作: DST←(DST)&(SRC) &-- 表示按位“与”运算 DST←(DST)|(SRC) |-- 表示按位“或”运算 DST←(DST)^(SRC) ^-- 表示按位“异或”运算 说明: 1 ) DST 、 SRC 可为通用寄存器、存储器操作数,SRC还可为立即数操作数, DST 和 SRC 不可同时为存储器操作数; 2 ) DST 、 SRC 数据类型必须一致,立即数可向上扩展; 3 )可进行 8 位或 16 位运算,根据 DST 数据类型决定; 4 )该指令影响 PF 、 SF 、 ZF 标志位,置 CF=0 、OF=0 。

Page 77: 第二章   80x86 汇编语言程序设计

77

AND/OR/XOR 指令示例: MOV AL , 32H

AND AL , OFH ;屏蔽某些位,或忽略高位 AND AX , AX ;值不变,使 CF=0

OR AL , 30H ;置位某些位,或高位加某个值 XOR AL , 00H ;值不变,使 CF=0

XOR AL , 0FH ;部分位按位取反 XOR AL , AL ;值置为 0 ,并清除所有所有标志位

思考:如何实现对某些位的置位和复位? 使寄存器值为零有哪些方法?哪种方案最好? 如何清除某些标志位?

Page 78: 第二章   80x86 汇编语言程序设计

78

( 3 ) TEST 测试指令 格式: TEST OPRD1 , OPRD2

操作: (OPRD1)&(OPRD2) ,结果不送给任何操作数 说明: 1 )该指令无目的操作数,即不改变任何操作数值; 2 )所有限制和对标志位的影响均与 AND 指令相同; 3 )该指令仅改变 FLAG 标志位,常用作转移条件。

转 62 页

TEST 指令示例: IN AL , 42H

TEST AL , O1H ;测试 bit0 是否为 1

JNZ SEND ; bit0=1(ZF≠1) 时转 SEND 处执行 思考: TEST 指令与 CMP 指令作为转移条件的应用范围有何不同?

Page 79: 第二章   80x86 汇编语言程序设计

79

2 、逻辑移位类指令( 1 )指令种类 移位指令: SHL—逻辑左移 SHR—逻辑右移 SAL—算术左移 SAR—算术右移 循环移位指令: ROL—循环左移 ROR—循环右移 RCL—带进位循环左移 RCR—带进位循环右移

Page 80: 第二章   80x86 汇编语言程序设计

80

( 2 )指令功能 移位指令:

逻辑左移 SHL或算术左移 SAL

CF

D7 D0

逻辑右移 SHR

CF

D7 D0

0

0

算术右移 SAR

CF

D7 D0

循环移位指令:

循环左移 ROL

CF

D7 D0

带进位循环左移 RCL

CF

D7 D0

循环右移 ROR

CF

D7 D0

带进位循环右移 RCR

CF

D7 D0

Page 81: 第二章   80x86 汇编语言程序设计

81

( 3 )指令格式 格式: OP DST , CNT

操作:对 DST ,按 OP 的移动规则移动 CNT 指定位数 说明: 1 ) DST 可为寄存器、存储器操作数; 2 ) CNT 可为立即数 ( 为 1 时 ) 、寄存器 ( 只能为 CL)操作数, 8086 以后机型, CNT 为立即数时值域为 1~31 ; 3 )可进行 8/16/32 位移位操作,由 DST 位数决定,DST 为存储器操作数时,由定义的数据类型决定; 4 )循环移位指令结果仅影响 CF 和 OF 标志位,其余指令结果影响OF 、 PF 、 SF 、 ZF 、 CF 标志位, 其中 --CF 由移入位决定, 若最后一次移位后最高位变化时则 OF=1 , SF 、 ZF 、 PF根据移位后的结果设置。

Page 82: 第二章   80x86 汇编语言程序设计

82

( 4 )指令示例 示例 1 : MOV CL , 5 ; 若 (AL)=0110 0100

(64H=100) SAR AL , CL ;执行后 (AL)=0000 0011 (03H=3) SAL AL , CL ;执行后 (AL)=0110 0000 (60H=96) ;逻辑 /算术左移相当于无 / 有符号数乘以 2N

;逻辑 /算术右移相当于无 / 有符号数除以 2N

示例 2 : 分析下列指令序列的功能 MOV CL , 4 SHL DX , CL MOV BL , AH SHL AX , CL SHR BL , CL OR DL , BL

AXDX

BL

4

44

功能:双字 DX:AX左移 4 位 ( 即双字乘以 4)

Page 83: 第二章   80x86 汇编语言程序设计

83

示例 3 :将无符号字节变量 Y 乘以 10, 积放在 AX 中。 方法一— MOV AL , Y ; AL←(Y) MOV CL , 10 MUL CL ; DST 为 AX 方法二— MOV AL, Y MOV AH, 0 SHL AX, 1 ; (Y)*2 MOV BX, AX SHL AX, 1 ; (Y)*4 SHL AX, 1 ; (Y)*8 ADD AX, BX ; (Y)*10 为什么要这么做? 示例 4 :将 AX 中 ASCII 码‘ 9’ 和‘ 6’ 转换成 AL 中压缩BCD 码 96 。 MOV CL , 4 SHL AH , CL ; 39H→90H AND AL , 0FH ; 36H→06H OR AL , AH

Page 84: 第二章   80x86 汇编语言程序设计

84

四、控制转移类指令 指令种类:无条件转移 JMP 、条件转移 Jx 、循环LOOP 、子程序调用 CALL/返回 RET 、中断 INT/ 中断返回IRET 。 转移地址:为转移目标处代码地址 ( 段地址 : 偏移地址 ) 。 * 段地址 -- 不一定是当前 CS 内容; * 偏移地址 -- 有 EA 和相对 IP 的位移量两种形式。 转移地址的寻址方式种类:

寻址方式 目标段地址 目标段内偏移地址

段内直接短转移 当前段地址

(当前 CS)

相对 IP 位移量(8/16 位位移量 )直接转移

间接转移 转移处 EA

(16 位 EA)段间 直接转移 转移处段地址( 非当前 CS)间接转移

说明:常规指令与控制转移指令的相对寻址所用段 REG 、基址REG 不同

Page 85: 第二章   80x86 汇编语言程序设计

85

转移地址寻址方式格式及效果表:段内转移 段间转移

地址格式 寻址效果 地址格式 寻址效果

直接

短转移 SHORT ADDR

或 ADDR

IP←(IP)+disp8

FAR PTR ADDR

IP←ADDREA

CS←ADDRSE

G

近转移NEAR PTR ADDR

或 ADDR

IP←(IP)+disp16

间接

立即数 不允许 无 不允许 无寄存器 16 位 reg IP←(reg)

存储器WORD PTR OPR

或 OPR

IP←(OPR) DWORD PTR OPR

IP←(OPR)CS←(OPR+2)

说明

直接寻址—转移 EA 在指令中;间接寻址—转移 EA 在 REG 或MEM 中;

ADDR— 地址标号 ( 只能是地址标号 ) ;disp— 汇编程序将 ADDR 转换为基于 IP 的偏移量放入指令中;ADDREA 和 ADDRSEG-- 汇编程序将 ADDR 对应 EA 和段基址放

入指令中;

16 位 reg— 只可为 16 位的基址 / 变址 REG ,转移 EA 放在

REG 中;

OPR— 转移 EA 放在 MEM 中,内容为转移目标处 EA[ 和段基

址 ]

回下页 回 87 页 回 88 页 回 92 页 回 95 页 转属性运算符 转分支程序

Page 86: 第二章   80x86 汇编语言程序设计

86

1 、 JMP 无条件转移指令 格式— JMP 转移地址 操作—按转移地址效果表得到 CS:IP

说明—支持全部 5 种转移寻址方式 例 1 :指令 JMP SHORT ADDT存放在 CS:0200H 中,标号 ADDT对于 IP 指针的偏移量为 1DH 。( 同 JMP ADDT 效果 )

0200H

B0H1DH

EBH1DH

0201H

0220H021FH

1DH

转移地址EA=0202H+1DH=021FH 例 2 : JMP BX ; (BX)=2000H

转移地址 EA=2000H ,转移物理地址=CS:2000H 。

转上页

例 3 : JMP WORD PTR[SI] ; (SI)=2000H

转移地址 EA=DS:2000H 处存储器中的内容。

Page 87: 第二章   80x86 汇编语言程序设计

87

例 4 :代码段 C1 中指令 JMP FAR

PTR NEXT 存放在 CS:0200H 中,内存数据如右图,求转移处的物理地址。

0200H

C1 段

EAH50H02H00H20H

C2 段NEXT

转 85 页

转移处段地址 =2000H ,转移处偏移地址 =0250H ,转移处物理地址=20250H 。(汇编时自动将 FAR PTR NEXT 转换为指令参数)

1400H 10H00H00H50H…

EA

SEG

例 5 :执行 JMP DWORD

PTR[400H] ,设 (DS)=100H , 内存数据如右图,求转移处物理地址。 转移处段地址 =5000H ,偏移地址 =0010H ,转移处物理地址=50010H 。

回 88 页

Page 88: 第二章   80x86 汇编语言程序设计

88

2 、 Jx 条件转移指令 格式— Jx 地址标号 操作—条件成立时,按转移地址效果表得到 CS:IP

否则, IP 为下条指令地址 说明—①仅支持段内直接短转移寻址方式 (故非转移地址,而为地址标号 )

(8 位位移量, CS 不变 )

②x 为转移条件标识符,转移条件种类有: 单个标志位条件 有符号数比较条件、无符号数比较条件 CX 是否为 0 条件

转 85 页 转 86 页

Page 89: 第二章   80x86 汇编语言程序设计

89

操作符 功能 测试条件JCJNC

进位标志为 1 时转移进位标志为 0 时转移

CF=1CF=0

JZ/JEJNZ/JNE

等于 0/ 相等时转移不等于 0/ 不相等时转移

ZF=1ZF=0

JSJNS

为负数时转移为正数时转移

SF=1SF=0

JOJNO

溢出时转移不溢出时转移

OF=1OF=0

JP/JPEJNP/JPO

偶状态时转移奇状态时转移

PF=1PF=0

( 1 )根据单个标志位转移的指令

回 91 页

Page 90: 第二章   80x86 汇编语言程序设计

90

( 2 )根据有 / 无符号数比较结果转移的指令转移条件

无符号数 有符号数指令 判断条件 指令 判断条件

A>B

JA/JNBE ZF=0且CF=0

JG/JNLE SF=OF且ZF=0

A≥B JAE/JNB ZF=1 或CF=0

JGE/JNL SF=OF 或ZF=1

A<B

JB/JNAE ZF=0且CF=1

JL/JNGL SF≠OF且ZF=0

A≤B JBE/JNA ZF=1 或CF=1

JLE/JNG SF≠OF 或ZF=1

( 3 )测试 CX 值为 0 时转移的指令 格式: JCXZ 地址标号 操作:若 (CX)=0 ,则按转移地址效果表得到CS:IP

说明:①转移地址寻址方式与 Jx 指令同 ( 段内直接短转移 ) ; ②仅判断 (CX)=0 ,不判断 ZF=1(硬件实现 ) 。

回下页 回 92 页

Page 91: 第二章   80x86 汇编语言程序设计

91

例 1 :将 MEM单元 X 中的十六进制数的 ASCII 形式转换为对应数值后存入单元 Y 中。 ASCII 中,‘ 0’~‘9’ 为 30H~39H , ‘A’~‘F’ 为 41H~46H MOV AH , X CMP AH , 39H JBE NEXT SUB AH , 7 ;’ A’~’F’→3AH~3FHNEXT : SUB AH , 30H ;30H~39H→0~9 MOV Y , AH 思考:实现 1 x> 0 y = 0 x=0 -1 x< 0

转 89 页 转上页

AH 为‘ A’~’F’?

AH=(X)

AH 为 3AH~3FH

AH=(AH)-30H

Y=(AH)

NY

Page 92: 第二章   80x86 汇编语言程序设计

92

3 、 LOOP/LOOPZ/LOOPNZ 循环指令 格式与操作—

指令格式 操作LOOP 地址标号 CX←(CX)-1

(CX)≠0 时转移LOOPZ/LOOPE 地址标号

CX←(CX)-1

(CX)≠0且 ZF=1 时转移LOOPNZ/LOOPNE 地址标号

CX←(CX)-1

(CX)≠0且 ZF=0 时转移

说明—仅支持段内直接短转移寻址方式; 若条件成立,按转移地址效果表得到 CS:IP 。 转移与循环主要差别:①自动计数②转移方向。

转 85 页转 90 页

Page 93: 第二章   80x86 汇编语言程序设计

93

例 1 :对长度为 10 的字节数组 ARRAY进行累加求和。 LEA SI , ARRAY ;取数组首址 MOV CX , 10 ;设置数组长度 MOV AX , 0AGAIN : ADD AL , [SI] ADC AH , 0 ;处理进位 INC SI LOOP AGAIN ;类似于 DEC CX 和 JNZ AGAIN ,但不同

例 2 :对长度为 N 、首址为 ARRAY 的字数组,将其中正数个数→DI , 0 的个数→ SI ,负数个数→ AX 。

思考 1 :对以 0FFH 结束的字节数组 ARRAY累加求和。

转下页 转 95 页

Page 94: 第二章   80x86 汇编语言程序设计

94

MOV CX, N MOV BX, 0 ;初始化,数组下标 MOV DI, BX ;正数个数 MOV SI, BX ; 0 的个数,负数个数 =N-DI-SI AGAIN: CMP ARRAY[BX], 0 ;数组当前元素与 0 比较 JLE LEEQ ;≤ 0 时转移 INC DI ;正数计数 JMP NEXT LEEQ: JL NEXT ;< 0 时转移 INC SI ; 0 计数 NEXT: ADD BX, 2 ;数组表指针指向下一元素 LOOP AGAIN MOV AX, N ;负数个数 =N-DI-SI SUB AX, DI SUB AX, SI

回上页

思考 2 :对首址为 STR 、长度为 N 的字符串,查找字符‘ $’ ,若找到则转 FOUND 处执行,否则转到NOT_FOUND

处执行。

Page 95: 第二章   80x86 汇编语言程序设计

95

4 、 CALL/RET 子程序调用 /返回指令 格式— CALL 转移地址 RET 或 RET EXP

转 85 页

操作— (支持 4 种转移寻址方式 )CALL RET RET EXP

段内

SP←(SP)-2((SP)+1,(SP))←(IP)

按转移地址得到CS:IP

IP←((SP)+1,(SP))SP←(SP)+2

① 同左

②SP←(SP)+EXP

段间

SP←(SP)-2((SP)+1,(SP))←(CS)SP←(SP)-2((SP)+1,(SP))←(IP)

按转移地址得到CS:IP

IP←((SP)+1,(SP))SP←(SP)+2CS←((SP)+1,(SP))SP←(SP)+2

① 同左

②SP←(SP)+EXP

回 97 页

Page 96: 第二章   80x86 汇编语言程序设计

96

例:分析执行下列程序时内存 ( 堆栈 ) 数据的变化。 ; C1 段 MAIN …… CALL FAR PTR PRO_A 0500:1000 …… ; C2 段 PRO_A …… CALL NEAR PTR PRO_B 2000:2500 …… CALL NEAR PTR PRO_C2000:3700 …... RET ; C2 段 PRO_B …… CALL NEAR PTR PRO_C 2000:4000 …… RET

; C2 段 PRO_C……RET

回下页 回 98 页

Page 97: 第二章   80x86 汇编语言程序设计

97

(1)MAIN调用 PROC_A之前 设 (SP)=0100 (2)MAIN调用 PROC_A之后

转上页 转 95 页

(3)PROC_A调用 PROC_B

之后2500

1000

0500

00FA

SP

(4)PROC_B调用 PROC_C

之后4000

2500

1000

0500

00F8

SP

(5)PROC_C返回 PROC_B

之后4000

2500

1000

0500

00FA

SP

1000

0500

00FC

SP低

0100

Page 98: 第二章   80x86 汇编语言程序设计

98

(6)PROC_B返回 PROC_A

之后4000

2500

1000

0500

00FC

SP

(7)PROC_A调用 PROC_C

之后4000

3700

1000

0500

00FA

SP

(8)PROC_C返回 PROC_A

之后4000

3700

1000

0500

00FC

SP

(9)PROC_A返回 MAIN之后

4000

3700

1000

0500

0100

SP

转 96 页

Page 99: 第二章   80x86 汇编语言程序设计

99

5 、 INT/IRET 中断 / 中断返回指令 格式— INT n

IRET

操作—INT n IRET

SP←(SP)-2((SP)+1,(SP))←(FLAG)SP←(SP)-2((SP)+1,(SP))←(CS)SP←(SP)-2((SP)+1,(SP))←(IP)IP←(0000:n*4)CS←(0000:n*4+2)

IP←((SP)+1,(SP))SP←(SP)+2CS←((SP)+1,(SP))SP←(SP)+2FLAG←((SP)+1,(SP))SP←(SP)+2

示例: INT 21H (注意子功能、参数及返回值)

Page 100: 第二章   80x86 汇编语言程序设计

100

常用 DOS 系统功能调用 (INT 21H) :功能号 调用参数 返回参数 功能

00 CS= 程序段前缀 程序终止 ( 同 INT 20H)

01 AL=输入字符 键盘输入并回显02 DL=输出字符 显示输出05 DL=输出字符 打印机输出07 AL=输入字符 键盘输入 ( 无回显 )

0A

DS:DX=缓冲区首址(DS:DX)=缓冲区最大字符数

(DS:DX+1)= 实际输入的字符数 键盘输入到缓冲区

0B AL=00 有输入AL=FF 无输入

检验键盘状态

4C AL=返回码 带返回码结束

DOS 中断: INT 20H~INT 3FH

INT 20H— 程序结束; INT 21H— 系统功能调用

Page 101: 第二章   80x86 汇编语言程序设计

101

五、串操作类指令 常规方法实现串传送 (BUFFA→BUFFB 、 25 字节 ) 例:

设置串操作指令的目的: 将串操作中常用指令串用新指令代替; 用默认参数代替自由参数,以简化编程。

MOV SI,OFFSET

BUFFA MOV DI,OFFSET BUFFB MOV CX,25 BEG: JCXZ EXIT

MOV AL,[SI] MOV [DI],AL

INC SI INC DI DEC CX JMP BEG EXIT: ……

回 104 页 回 105 页

Page 102: 第二章   80x86 汇编语言程序设计

102

1 、串操作指令类型及功能 指令类型: MEM-MEM 类型: MOVS— 串传送、 CMPS—串比较; REG-MEM 类型: SCAS— 串扫描、 LODS—装入串、 STOS— 存储串; I/O-MEM 类型: INS— 串输入、 OUTS— 串输出。

串操作功能实现方法: ① 通过串操作指令实现对串中数据的操作并自动调整地址,支持按字节、字、双字数据类型操作;  ②通过指令的重复前缀实现串操作功能; ③通过按递增或递减调整地址提高操作灵活性。

回下页

Page 103: 第二章   80x86 汇编语言程序设计

103

( 1 )串操作指令 指令格式:只有操作码字段。

串传送 串比较 串扫描 装入串 存储串 串输入 串输出MOVS

BMOVS

WMOVS

D

CMPSB

CMPSW

CMPSD

SCASB

SCASW

SCASD

LODSB

LODSW

LODSD

STOSB

STOSW

STOSD

INSBINSWINSD

OUTSB

OUTSW

OUTSD

CPU 设计时对串操作指令的规定: ① 各指令中 MEM 类型源、目的串地址由 DS:SI 、 ES:DI

指定; ②REG-MEM 类指令, REG 只能为 AL 、 AX 、 EAX ; ③I/O-MEM 类指令, I/O 地址只能存放在 DX 中; ④地址调整方向由 FLAG 中 DF 位决定 (DF=0 时为递增方向、 DF=1 时为递减方向 ) ,步长由数据类型决定(±1 、 ±2 、 ±4) 。 DF 位的置位和复位通过 STD 指令和 CLD 指令实现

转上页 转 52 页

Page 104: 第二章   80x86 汇编语言程序设计

104

课件 P100 例题用串操作指令实现: MOV SI,OFFSET BUFFA ;源串 DS:SI MOV DI,OFFSET BUFFB ;目的串 ES:DI MOV CX,25 CLD ;递增方向 BEG: JCXZ EXIT MOVSB DEC CX JMP BEG EXIT: ……

转 101 页

Page 105: 第二章   80x86 汇编语言程序设计

105

( 2 )串操作指令的重复前缀 对重复前缀的规定:重复操作的次数必须放在 CX 中

格式 功能 说明REP CX≠0 时重复

{CX←(CX)-1 、执行串操作指令 }

不满足重复条件时,转去执行下条指令

REPZ/REPE

CX≠0且 ZF=1 时重复{CX←(CX)-1 、执行串操作命令 }

REPNZ/REPNE

CX≠0且 ZF=0 时重复{CX←(CX)-1 、执行串操作命令 }

课件 P100 例题用带重复前缀的串操作指令实现: MOV SI,OFFSET BUFFA MOV DI,OFFSET BUFFB MOV CX,25 CLD REP MOVSB

转 101 页

Page 106: 第二章   80x86 汇编语言程序设计

106

重复前缀与串操作指令的应用组合:REP REPZ REPNZ

MEM-MEM

MOVS

一组数据 (CX个 )传送

无意义

CMPS

无意义 比较两串是否相同

查找两串中相同数据位置

REG-MEM

SCAS

无意义 查找第一个不同 / 相同数据位置

LODS

无意义 无意义 (需使用循环 )

STOS

给串赋初值 无意义

I/O-MEM

INS 读数据块到MEM

无意义 (需使用循环 )

OUTS

写数据块到I/O

无意义 (需使用循环 )

Page 107: 第二章   80x86 汇编语言程序设计

107

2 、串操作指令应用举例 MOVS 指令示例:说明下段程序执行效果 MOV SI, 0050H ; (DS)=2000H MOV DI, 0100H ; (ES)=3000H MOV CX, 5 CLD REP MOVSB

SCAS 指令示例:教材 P89 例 3.14

Page 108: 第二章   80x86 汇编语言程序设计

108

综合应用示例: 将存储区 A到 A+i 中的数据传送到存储区 B到 B+i中,要求存放的顺序与原先的顺序相反。 LEA SI, A LEA DI, B ADD DI, i ; DI 指向存储区 B 的末尾 MOV CX, i+1 ;串的长度LP: CLD ; DF=0 LODSB ;从源区取一数据 STD ; DF=1 ,改变方向 STOSB ;存入目的区 DEC CX JNZ LP

回下页

Page 109: 第二章   80x86 汇编语言程序设计

109

六、处理器控制类指令 有 FLAG 标志位操作、 CPU控制 2 类指令。1 、标志位操作指令 CLC —— 进位标志 CF 置 0 ( 即让 CF=0) STC —— 进位标志 CF 置 1 ( 即让 CF=1) CMC —— 进位标志 CF求反 ( 即让 CF=~CF)

CLD —— 方向标志 DF 置 0 ( 即让DF=0)

STD —— 方向标志 DF 置 1 ( 即让DF=1)

CLI —— 中断标志 IF 置 0 ( 即让 IF=0) STI —— 中断标志 IF 置 1 ( 即让 IF=1)

转上页

Page 110: 第二章   80x86 汇编语言程序设计

110

2 、 CPU控制指令 NOP —— 空操作 HLT —— 停机 WAIT —— 等待 ESC —— 换码 LOCK —— 封锁 BOUND——界限 ENTER—— 建立堆栈帧 LEAVE——释放堆栈帧

BOUND 、 ENTER 、 LEAVE 非 8086 指令

Page 111: 第二章   80x86 汇编语言程序设计

111

上机实验要求: ⑴抄一最小程序,熟悉上机流程、 DEBUG 的用法; ⑵抄一含数据段、附加段、堆栈段程序,改变代码段内容,熟悉 8086 各类寻址方式含义; ⑶改变程序,熟悉 8086 各类指令的细节,如MOV 等; 前两小节学习完成时,完成上述实验 ⑷改变程序,熟悉 8086 各类伪指令的功能,如测试程序加载后、各段寄存器的值在不同定义时的变化; 第三小节学习完成时,完成上述实验 ⑸按“汇编语言程序设计实验要求”完成三个小实验。 第四小节学习完成时,完成上述实验