Chapter5
教学提示
在学习和应用汇编语言进行
程序设计时, 有一些经常遇
到的问题, 例如算术运算,
代码转换等, 需要掌握
CHAPTER 5 程序设计基本技术
一、汇编语言程序的设计步骤
1、分析问题,建立数学模型 — 对问题的数学描述
2、确定算法 — 方法和步骤
3、编制程序流程图
处理框 判断框 起止框 连接框
流向线
4、合理分配存储空间和寄存器
寄存器、存储器(常数单元、数据单元和结果单元)
5、编制程序
概述
6、调式和运行程序
( 1)使用编辑程序编辑好源程序文件(,asm)
( 2)使用宏汇编程序( MASM)将源程序文
件(,asm)汇编成目标文件(,obj)
( 3)使用连接程序( LINK),将目标文件
(,obj)连接装配成可执行文件(,EXE)
( 4)使用调式程序( DEBUG),调式可执行
文件,分析结果
概述
概述
二、程序的基本结构
1、顺序结构程序
2、分支结构程序
3、循环(重复)结构程序
顺序结构 分支结构 循环(重
复)结构
顺序结构程序设计
?顺序结构程序完全按指令书写的
前后顺序执行每一条指令, 是最
基本, 最常见的程序结构
?特点
顺序性, 结构简单, 只适应于简
单问题的处理
例 1 计算
例 2 移位
例,X+Y+Z W
stack segment para stack
dw 64h dup(?)
stack ends
data1 segment
X dw 5
Y dw 6
Z dw 7
W dw?
data1 ends
code segment
assume cs:code,
ss:stack,ds:data1
start:mov ax,data1
mov ds,ax
mov ax,X
add ax,Y
adc ax,Z
mov W,ax
mov ah,4ch
int 21h
code ends
end start
例,64位数据移位data segment
var db 21h,43h,65h,87h,78h,56h,12h,34h
data ends
code segment
assume cs:code,ds:data
start:mov ax,data
mov ds,ax
mov al,var[6]
mov var[7],al
mov al,var[5]
mov var[6],al
mov al,var[4]
mov var[5],al
mov al,var[3]
mov var[4],al
图示
mov al,var[2]
mov var[3],al
mov al,var[1]
mov var[2],al
mov al,var[0]
mov var[1],al
mov byte ptr var[0],0
mov ah,4ch
int 21h
code ends
end start
12 34 56 78 87 65 43 21h
34 56 78 87 65 43 21 00h移位后
图示
例,64位数据移位
程序结束的方法
程序执行完毕,正常结束要返回 DOS,有两种方法
( 1)使用 PSP中的,INT 20H”指令,实现用户程
序结束,返回 DOS
方法,① 将用户程序设置成一个远过程
② 程序开始时,执行如下指令
PUSH DS
MOV AX,0
PUSH AX
③ 用户程序结束时,用 RET指令
程序结束的方法
( 2)使用 DOS功能调用的,INT 21H”指令,实现
用户程序结束,返回 DOS
方法,在程序结束前,使用 如下指令
MOV AH,4CH
INT 21H
注意:一般情况下,使用第 2种方法结束用户程序。
分支结构程序设计
?分支结构程序根据条件是真或假决定
执行与否
?判断的条件是各种指令, 如 CMP、
TEST等执行后形成的状态标志
?转移指令 Jxx和 JMP可以实现分支控制
控制转移类指令
?控制转移类指令 用于实现分支, 循环,
过程等程序结构, 是仅次于传送 指令
的最常用指令
重点掌握,JMP/Jxx/LOOP CALL/RET
INT n/IRET 常用系统功能调用
一般了解,LOOPZ/LOOPNZ INTO
控制转移类指令通过 改变 IP( 和 CS) 值,
实现程序执行顺序的改变
无条件转移指令
?只要执行无条件转移指令 JMP,就使程序转到
指定的目标地址处, 从目标地址处开始执行那
里的指令
?操作数 label是要转移到的 目标地址 ( 目的地
址, 转移地址 )
? JMP指令分成 4种类型:
⑴ 段内转移, 直接寻址
⑵ 段内转移, 间接寻址
⑶ 段间转移, 直接寻址
⑷ 段间转移, 间接寻址
JMP label ;程序转向 label标号指定的地址
JMP
目标地址的寻址方式
?直接寻址方式
?转移地址象立即数一样, 直接在
指令的机器代码中, 就是直接寻
址方式
?间接寻址方式
?转移地址在寄存器或主存单元中,
就是通过寄存器或存储器的间接
寻址方式
用标号表达
用寄存器或存储器
操作数表达
JMP
目标地址的范围:段内
?段内转移 —— 近转移 ( near)
?在当前代码段 64KB范围内转移
( ± 32KB范围 )
?不需要更改 CS段地址, 只要改
变 IP偏移地址
?段内转移 —— 短转移 ( short)
?转移范围可以用一个字节表达,
在段内- 128~+ 127范围的转移






JMP
目标地址的范围:段间
?段间转移 —— 远转移 ( far)
?从当前代码段跳转到另一个
代码段, 可以在 1MB范围
?需要 更改 CS段地址和 IP偏移
地址
?目标地址必须用一个 32位数
表达, 叫做 32位远指针, 它
就是逻辑地址






实际编程时, 汇编程序会根据目标地址的距离,
自动处理 成短转移, 近转移或远转移
程序员可用操作符 near ptr 或 far ptr 强制
JMP
JMP段内转移, 直接寻址
JMP label ; IP←IP+ 位移量
? 位移量是紧接着 JMP指令后的那条指令的偏移地址,
到目标指令的偏移地址的地址位移
? 当向地址增大方向转移时, 位移量为正;向地址减
小方向转移时, 位移量为负
jmp again ;转移到 again处继续执行……
again,dec cx ;标号 again的指令……
jmp output ;转向 output……
output,mov result,al ;标号 output的指令
实际为相对寻址
段内转移, 间接寻址
JMP r16/m16 ; IP←r 16/m16
? 将一个 16位寄存器或主存字单元内容送入 IP
寄存器, 作为新的指令指针, 但不修改 CS寄存
器的内容
jmp ax ; IP←AX
jmp word ptr [2000h] ; IP←[ 2000h]
JMP
段间转移, 直接寻址
JMP far ptr label; IP←label 的偏移地址; CS←label 的段地址
?将标号所在段的段地址作为新的 CS值,
标号在该段内的偏移地址作为新的 IP值;这
样, 程序跳转到新的代码段执行
jmp far ptr otherseg;远转移到代码段 2的 otherseg
JMP
段间转移, 间接寻址
JMP far ptr mem; IP←[mem], CS←[mem+ 2]
? 用一个双字存储单元表示要跳转的目标地
址 。 这个目标地址存放在主存中连续的两个
字单元中的, 低位字送 IP寄存器, 高位字送
CS寄存器
mov word ptr [bx],0
mov word ptr [bx+2],1500h
JMP far ptr [bx] ;转移到 1500h:0
JMP
条件转移指令
?指定的条件 xx如果成立, 程序转移到
由 label( 目标地址 ) 指定的目标地址处
去执行指令;条件不成立, 则程序将
顺序执行下一条指令
?操作数 label( 目标地址 ) 是采用短转移,
称为相对寻址方式
Jxx
Jxx label;条件满足,发生转移,IP←IP + 8位位移量;条件不满足,顺序执行
相对寻址方式
? Jxx指令的操作数 label是一个标号
?一个 8位位移量, 表示 Jxx指令后的那条
指令的偏移地址, 到目标指令的偏移地址
的地址位移
? 8位位移量是 相对于 当前 IP的, 且距当前
IP地址- 128~+ 127个单元的范围之内,
属于段内短距离转移
? Jxx目标地址就采用这种 相对寻址方式
? Jxx指令为 2个字节, 条件不满足时的
顺序执行就是当前指令偏移指针 IP加 2
Jxx
Jxx指令的分类
?Jxx指令不影响标志, 但要利用标
志 ( 下表 ) 。 根据利用的标志位
不同, 17条指令分成 4种情况:
⑴ 判断单个标志位状态
⑵ 比较无符号数高低
⑶ 比较有符号数大小
⑷ 判断计数器 CX为 0
Jxx
判断单个标志位状态
?这组指令单独判断 5个状态标志之一
⑴ JZ/JE和 JNZ/JNE:利用零标志 ZF,判断结
果是否为零 ( 或相等 )
⑵ JS和 JNS:利用符号标志 SF,判断结果是
正是负
⑶ JO和 JNO:利用溢出标志 OF,判断结果是
否产生溢出
⑷ JP/JPE和 JNP/JPO:利用奇偶标志 PF,判
断结果中, 1”的个数是偶是奇
⑸ JC/JB/JNAE和 JNC/JNB/JAE:利用进位
标志 CF,判断结果是否进位或借位
Jxx
例题
例题
例题
例题
例题
比较无符号数高低
?无符号数的大小用高 ( Above) 低
( Below) 表示
?利用 CF确定高低, 利用 ZF标志确定相
等 ( Equal)
?两数的高低分成 4种关系:
⑴ 低于 ( 不高于等于 ), JB( JNAE)
⑵ 不低于 ( 高于等于 ), JNB( JAE)
⑶ 低于等于 ( 不高于 ), JBE( JNA)
⑷ 不低于等于 ( 高于 ), JNBE( JA)
Jxx
无符号数条件转移指令(执行 A-B操作)
指令 条件 意义
JA/JNBE CF=0 AND ZF=0 A>B
JAE/JNB CF=0 OR ZF=1 A≥ B
JB/JNAE CF=1 AND ZF=0 A<B
JBE/JNA CF=1 OR ZF=1 A≤ B
例:比较无符号数
cmp ax,bx ;比较 ax和 bx
jnb next ;若 ax≥ bx,转移
xchg ax,bx ;若 ax< bx,交换
next,...
结果,AX保存较大的 无符号数
比较有符号数大小
?有符号数的大 ( Greater) 小 ( Less)
需要组合 OF,SF标志, 并利用 ZF标
志确定相等 ( Equal)
?两数的大小分成 4种关系:
⑴ 小于 ( 不大于等于 ), JL( JNGE)
⑵ 不小于 ( 大于等于 ), JNL( JGE)
⑶ 小于等于 ( 不大于 ), JLE( JNG)
⑷ 不小于等于 ( 大于 ), JNLE( JG)
Jxx
有符号数条件转移指令(执行 A-B操作)
指令 条件 意义
JG/JNLE SF=OF AND ZF=0 A>B
JGE/JNL SF=OF OR ZF=1 A≥ B
JL/JNGE SF≠ OF AND ZF=0 A<B
JLE/JNG SF≠ OF OR ZF=1 A≤ B
例:比较有符号数
cmp ax,bx ;比较 ax和 bx
jnl next ;若 ax≥ bx,转移
xchg ax,bx ;若 ax< bx,交换
next,...
结果,AX保存较大的 有符号数
计数器 CX为 0转移
?这是一条较特殊的指令
?CX寄存器通常在程序中用做计数器
?JCXZ指令用来判断计数是否为 0
JCXZ label; CX= 0,发生转移,IP←IP + 8位位移量; CX≠0,顺序执行
判断计数器为 0
mov cx,100
again,movsb ;传送一个字节
dec cx ;传送次数减 1
jnz again ;判断传送次数 cx是否为 0;不为 0( ZF=0), 则转移;否则, 结束
mov cx,100
again,jcxz next ;判断传送次数 cx是否为 0
movsb
dec cx
jmp again
next,...
cmp cx,0
jz next
单分支程序设计
?条件成立跳转,
否则顺序执行分
支语句体;注意
选择正确的条件
转移指令和转移
目标地址
例:求绝对值;计算 X- Y的绝对值
mov ax,X
sub ax,Y
jns nonneg ;条件满足 ( X-Y≥ 0)?
neg ax ;条件不满足, 求补
nonneg,mov result,ax ;条件满足;计算 AX的绝对值
sub ax,0
jge nonneg ;条件满足 ( AX≥ 0)?
neg ax ;条件不满足, 求补
nonneg,mov result,ax ;条件满足
双分支程序设计
条件成立跳转执行第
2个分支语句体, 否
则顺序执行第 1个分
支语句体 。 注意第 1
个分支体后一定要有
一个 JMP指令跳到第
2个分支体后
Jxx;寄存器 AL中是字母 Y或 y,在令 AH= 0;否则
令 AH=- 1
cmp al,’Y’ ;AL是大写 Y否?
jz next ;是, 转移
cmp al,’y’ ;AL是小写 y否?
jz next ;是, 转移
mov ah,-1 ;不是 Y或 y,在 AH=- 1,结束
jmp done ;一定要跳过另一个分支体
next,mov ah,0 ;是 Y或 y,在 AH= 0,结束
done,...
例题 单分支和双分支
多分支程序设计
?多个条件对应各自的分支语句体, 哪个条
件成立就转入相应分支体执行 。 多分支可以
化解为双分支或单分支结构的组合, 例如:
or ah,ah ;等效于 cmp ah,0
jz function0 ;ah= 0,转向 function0
dec ah ;等效于 cmp ah,1
jz function1 ;ah= 1,转向 function1
dec ah ;等效于 cmp ah,2
jz function2 ;ah= 2,转向 function2
图示
分支结构程序设计
一、用, 比较 /测试 -分支结构, 实现分支结构的程序设
计 方法,先根据要处理的问题进行比较、测试或者
进行算术运算、逻辑运算,以产生标志寄存器中
能表达的“标志”,如:
地址的高低、两个数的大小、数的正负,是
否为,0”,某位是,0”还是,1”等。
然后根据“标志”进行条件转移。
例 1:编写一段程序计算以下公式
1 x>0
y= 0 x=0
-1 x<0
cmp x,0
jge biger
mov y,-1
jmp next
biger:jz equl
mov y,1
jmp next
equl,mov y,0
Next,……
……
Y -1 Y 0 Y 1
x ≥0?
x =0?
y
y
n n
分支结构程序设计
分支结构程序设计
例 2:数据快的搬移程序
分析,( 1) 数据快的三种分布情况



























分支结构程序设计
( 2)搬移方法
当源数据块首地址 >目的数据块首地址时,从源
数据块首地址单元开始搬移。
当源数据块首地址 <目的数据块首地址时,从源
数据块末地址单元开始搬移。
开始
预置 DS
SI 源数据块首址
DI 目的据块首址
CX 传送字节数
(SI)>(DI)?
SI (SI)+(CX)-1
DI (DI)+(CX)-1
(DI) ((SI))
SI (SI) -1
DI (DI) -1
(CX) (CX)-1
(DI) ((SI))
SI (SI) +1
DI (DI) +1
(CX)>0?
结束
yn
n
y y
分支结构程序设计
DATA SEGMENT
ORG $+20H
STRG DB 3H DUP(‘ABCDEFG’)
BLOK1 DW STRG+5
BLOK2 DW STRG+15
LENG EQU 10
DATA ENDS
STACK1 SEGMENT PARA STACK
DW 20H DUP(0)
STACK1 ENDS
COSEG SEGMENT
ASSUME CS:COSEG,DS:DATA,SS:STACK1
BEGIN,MOV AX,DATA
MOV DS,AX
MOV CX,LENG
MOV SI,BLOK1
MOV DI,BLOK2
CMP SI,DI
JA BIGER
ADD SI,LENG-1
ADD DI,LENG-1
LITER,MOV AL,[SI]
MOV [DI],AL
DEC SI
DEC DI
DEC CX
JNE LITER
JMP END1
BIGER,MOV AL,[SI]
MOV [DI],AL
INC SI
INC DI
DEC CX
JNE BIGER
END1,MOV AH,4CH
INT 21H
COSEG ENDS
END BEGIN
分支结构程序设计
二、用, 跳转表, 实现多路分支结构的程序设
计 1、什么是跳转表?
在分支结构程序中,将转入的目标地址或转移指令
组成一个表,则称这个表为跳转表,也就是说,跳转表
中存放的是若干个要转移的目标地址,或若干个无条件
转移指令。
2、用跳转表实现分支程序的方法
( 1)组成跳转表
( 2)根据跳转表寻址到相应的转移地址或找到相应
的转移指令,从而实现分支转移。
分支结构程序设计
3、举例
( 1)跳转表中存放转移地址,..
disp1
disp2
disp3
dispn
tabel
1
2
3
n
?先组成如右图所示的跳转表
..
.
?转移地址的寻址
由于每个转移地址( 16位)占两
个字节,故转移地址在跳转表中的地
址为 (n-1) × 2。
如将这个地址 BX中,则可用
如下指令实现跳转,JMP tabel[BX]
注意:跳转表中的地址可直接用
目标地址(标号)。
地址表形成多分支
?需要在数据段事先安排一个按顺序排
列的转移地址表
?输入的数字作为偏移量 。 因为只有 2个
字节 16位偏移地址, 所以偏移量需要
乘 2
?关键是要理解间接寻址方式 JMP指令
地址表 分支 1地址 分支 2地址,..
Table dw disp1,disp2,disp3,disp4,...
data segmnt
msg db'Input Number(1-8):',0dh,0ah,'$'
msg1 db 'Chapter 1,,..',0dh,0ah,'$'
msg2 db 'Chapter 2,,..',0dh,0ah,'$'
...
msg8 db 'Chapter 8,,.,',0dh,0ah,'$'
tabledw disp1,disp2,disp3,disp4
dw disp5,disp6,disp7,disp8
data ends;取得各个标号的偏移地址
例,数据段- 1/3
此处等同于 offset disp1
codeseg segment
assume cs:codeseg,ds:data
start1,mov dx,offset msg;提示输入数字
mov ah,9
int 21h
mov ah,1 ;等待按键
int 21h
cmp al,'1' ;数字 < 1?
jb start1
cmp al,'8' ;数字 > 8?
ja start1
and ax,000fh ;将 ASCII码转换成数字
例,代码段- 2/3
dec ax
shl ax,1 ;等效于 add ax,ax
mov bx,ax
jmp table[bx];( 段内 ) 间接转移,IP←[table+bx]
start2,mov ah,9
int 21h
mov ah,4ch
int 21h
disp1,mov dx,offset msg1 ;处理程序 1
jmp start2
...
code ends
end start1
例, 代码段- 3/3
可以改为 call table[bx]
对应修改为 ret
分支结构程序设计
( 2)跳转表中存放转移地址
..
.
Jmp disp1
tabel
1
2
3
n
在跳转表中保存若干条无
条件转移指令,在程序中,先
寻址到跳转表中相应的转移指
令位置,然后转移到这个位置,
就可以实现各种分支转移。
..
.
由于 jmp dispi指令占 3个字节,
故转移地址在跳转表中的地址为
tabel+(n-1) × 3。
如将这个地址 BX中,则可用
如下指令实现跳转,JMP BX
Jmp disp2
Jmp disp3
Jmp dispn
程序举例
data segment
N db 3
data ends
stack1 segment para stack
dw 20h dup(0)
stack1 ends
Code segment
assume cs:code,ds:data,ss:stack
start,mov ax,data
mov ds,ax
……
mov bh,0
mov bl,n
dec bl
mov al,bl
shl bl,1
add bl,al
add bx,offset itable
jmp bx
Itable,jmp disp1
jmp disp2
jmp disp3
……
jmp dispn
disp1,……
jmp end1
disp2,……
jmp end1
disp3,……
jmp end1
……
dispn,……
end1,mov ah,4ch
int 21h
code ends
end start
循环程序设计
?循环结构一般是根据某一条件判断为
真或假来确定是否重复执行循环体
?循环指令和转移指令可以实现循环控
制;还可以采用 MASM 6.x提供的循环
控制伪指令实现
循环结构
结束
初始化 循环的初始状态
循环体
循环的工作部分
及修改部分
计数控制循环
条件控制循环
修改部分
控制条件Y
N
循环指令 ( loop)
?循环指令利用 CX计数器自动减 1,
方便实现计数循环的程序结构
?label操作数采用相对寻址方式
LOOP label ; CX←CX - 1,; CX≠0,循环到标号 label
LOOPZ label ; CX←CX - 1,; CX≠0 且 ZF= 1,循环到标号 label
LOOPZ label ; CX←CX - 1,; CX≠0 且 ZF= 0,循环到标号 label
例:记录空格个数
mov cx,count ;设置循环次数
mov si,offset string
xor bx,bx ; bx清 0,用于记录空格数
mov al,20h
again,cmp al,es:[si]
jnz next ; ZF=0,非空格, 转移
inc bx ; ZF=1,是空格, 个数加 1
next,inc si
loop again;字符个数减 1,不为 0继续循环
dec cx
jnz again
子程序指令
?子程序是完成特定功能的一段程序
?当主程序 ( 调用程序 ) 需要执行这个
功能时, 采用 CALL调用指令转移到该
子程序的起始处执行
?当运行完子程序功能后, 采用 RET返
回指令回到主程序继续执行
演示
子程序调用指令
?CALL指令分成 4种类型 ( 类似 JMP)
CALL label ;段内调用, 直接寻址
CALL r16/m16 ;段内调用, 间接寻址
CALL far ptr label ;段间调用, 直接寻址
CALL far ptr mem ;段间调用, 间接寻址
?CALL指令需要保存返回地址:
? 段内调用 —— 入栈偏移地址 IP
SP←SP - 2,SS:[SP]←IP
? 段间调用 —— 入栈偏移地址 IP和段地址 CS
SP←SP - 2,SS:[SP]←IP
SP←SP - 2,SS:[SP]←CS
CALL
子程序返回指令
?根据段内和段间, 有无参数, 分成 4种类型
RET ;无参数段内返回
RET i16 ;有参数段内返回
RET ;无参数段间返回
RET i16 ;有参数段间返回
?需要弹出 CALL指令压入堆栈的返回地址
? 段内返回 —— 出栈偏移地址 IP
IP←SS,[SP],SP←SP + 2
? 段间返回 —— 出栈偏移地址 IP和段地址 CS
IP←SS,[SP],SP←SP + 2
CS←SS,[SP],SP←SP + 2
i16参数的作用
RET
例:子程序;主程序 mov al,0fh ;提供参数 AL
call htoasc ;调用子程序
...;子程序,将 AL低 4位的一位 16进制数 转换 成 ASCII码
htoasc:and al,0fh ;只取 al的低 4位
or al,30h ; al高 4位变成 3
cmp al,39h ;是 0~ 9,还是 0Ah~ 0Fh
jbe htoend
add al,7 ;是 0Ah~ 0Fh,加上 7
htoend:ret ;子程序返回
转换原理
中断指令
?中断 ( Interrupt ) 是又一种改变
程序执行顺序的方法
?中断具有多种中断类型
?中断的指令有 3条:
INT i8 IRET INTO
?本节主要掌握类似子程序调用指
令的中断调用指令 INT i8,进而学
习使用 DOS功能调用
中断指令 INT
INT i8;中断调用指令:产生 i8号中断
IRET;中断返回指令:实现中断返回
INTO;溢出中断指令:;若溢出标志 OF=1,产生 4号中断;否则顺序执行
系统功能调用
? 21H号中断是 DOS提供给用户的用于
调用系统功能的中断, 它有近百个功能
供用户选择使用, 主要包括设备管理,
目录管理和文件管理三个方面的功能
? ROM-BIOS也以中断服务程序的形式,
向程序员提供系统的基本输入输出程序
?汇编语言程序设计需要采用系统的各
种功能程序
? 充分利用操作系统提供的资源是程序
设计的一个重要方面, 需要掌握
功能调用的格式
通常按照如下 4个步骤进行:
⑴ 在 AH寄存器中设置系统功能调用号
⑵ 在指定寄存器中设置入口参数
⑶ 执行指令 INT 21H( 或 ROM-BIOS的中
断向量号 ) 实现中断服务程序的功能
调用
⑷ 根据出口参数分析功能调用执行情况
输入输出类功能调用
?向显示器输出字符
⒈ 字符的输出
⒉ 字符串的输出
?从键盘输入数据
⒊ 字符的输入
⒋ 字符串的输入
⒌ 按键的判断
裸机
汇编语言程序
字符输出的功能调用
?DOS功能调用 INT 21H
?功能号,AH= 02H
?入口参数,DL=字符的 ASCII码
?功能:在显示器当前光标位置显示
给定的字符, 光标右移一个字符位
置 。 如按 Ctrl-Break或 Ctrl-C则退出
例:显示问号;在当前显示器光标位置显示一个问号
mov ah,02h ;设置功能号,ah← 02h
mov dl,'?' ;提供入口参数,dl←'?'
int 21h ; DOS功能调用:显示
进行字符输出时, 当输出响铃字符
( 07H ) 以 及 退 格 ( 08H ), 回车
( 0DH) 和换行 ( 0AH) 字符时, 该功
能调用可以自动识别并能进行相应处理
字符输出的功能调用
?显示器功能调用 INT 10H
?功能号,AH= 0EH
?入口参数,AL=字符的 ASCII码
BL=字符的颜色值 ( 图形方式 )
BH=页号 ( 字符方式 )
通常使 BX= 0
?功能:将字符按原属性在光标处显
示, 光标自动移到下一个字符位置
字符串输出的功能调用
?DOS功能调用 INT 21H
? 功能号,AH= 09H
? 入口参数:
DS:DX=欲显示字符串在主存中的首地址
字符串应以 $( 24H) 结束
? 功能:在显示器输出指定的字符串
?可以输出回车 ( 0DH) 和换行 ( 0AH)
字符产生回车和换行的作用
例:显示字符串
string db 'Hello,Everybody !',0dh,0ah,'$';在数据段定义要显示的字符串
...
mov ah,09h;设置功能号,ah← 09h
mov dx,offset string;提供入口参数,dx← 字符串的偏移地址
int 21h; DOS功能调用:显示
字符输入的功能调用
?DOS功能调用 INT 21H
?功能号,AH= 01H
?出口参数,AL=字符的 ASCII码
?功能:获得按键的 ASCII代码值
?调用此功能时, 若无键按下, 则
会一直等待, 直到按键后才读取
该键值
例:判断按键
getkey,mov ah,01h ;功能号,ah← 01h
int 21h ;功能调用
cmp al,’Y’ ;处理出口参数 al
je yeskey ;是, Y”
cmp al,’N’
je nokey ;是, N”
jne getkey
...
yeskey,...
nokey,...
字符输入的功能调用
?键盘功能调用 INT 16H
? 功能号,AH= 0
? 出口参数,AX=键值代码
对于标准 ASCII码按键,AL= ASCII码,
AH=扫描码;
对于扩展按键,AL= 00H,AH=键扩展码;
对于 alt+小键盘数字按键,AL= ASCII码,
AH= 00H
?此功能类同 DOS功能 01H,会一直等
待按键
例:字符输入输出
mov ah,0 ;键盘功能调用 ( int 16h)
int 16h ; al← 按键的 ASCII码
mov bx,0 ;显示功能调用 ( int 10h)
mov ah,0eh
int 10h ;显示
字符串输入的功能调用
?DOS功能调用 INT 21H
? 功能号,AH= 0AH
? 入口参数,DS:DX=缓冲区首地址
?执行该功能调用时, 用户按键, 最后
用回车确认
?本调用可执行全部标准键盘编辑命令;
用户按回车键结束输入, 如按 Ctrl+
Break或 Ctrl+ C则中止
关键要定义好缓冲区
例:输入字符串
buffer db 81 ;定义缓冲区;第 1个字节填入可能输入的最大字符数
db 0 ;存放实际输入的字符数
db 81 dup(0) ;存放输入的字符串
...
mov dx,seg buffer;伪指令 seg取得 buffer的段地址
mov ds,dx ;设置数据段 DS
mov dx,offset buffer
mov ah,0ah
int 21h
按键判断的功能调用
?DOS功能调用 INT 21H
?功能号,AH= 0BH
?出口参数,AL= 0,当前没有按键;
AL= FFH,当前已经按键 。
?功能:仅判断当前是否有按下的键,
设置 AL后退出
例:按任意键继续
..,;提示, 按任意键继续,
getkey:mov ah,0bh
int 21h
or al,al ; al= 0?
jz getkey; al= 0,没有按键, 继续等待;等同于如下功能调用
mov ah,01h
int 21h
按键判断的功能调用
?键盘功能调用 INT 16H
? 功能号,AH= 1
? 出口参数:若标志 ZF= 1,无键按下;
若 ZF= 0,有键按下, 且 AX=键值代码
? 功能:此子功能仅判断是否按键, 设置零
位标志 ZF后退出
?这两个功能调用都不循环等待按键,
即使有键按下, 键盘缓冲区仍然保留
键值并且没有被清空, 必要时必须用
字符输入功能取走键值清空缓冲区
处理机控制类指令
?这些指令在特定的情况下, 必须使用
?对标志位进行设置的指令
? CLC STC CMC
? CLD STD
? CLI STI
?对 CPU状态进行控制的指令
? NOP CS,SS,DS,ES:
? LOCK HLT ESC WAIT
进位标志操作指令
?用于任意设置进位标志
CLC ;复位进位标志,CF← 0
STC ;置位进位标志,CF← 1
CMC ;求反进位标志,CF← ~ CF
方向标志操作指令
串操作指令中, 需要使用
CLD ;复位方向标志,DF← 0
STD ;置位方向标志,DF← 1
中断标志操作指令
?在编写中断服务程序时, 需要
控制可屏蔽中断的允许和禁止
CLI ;复位中断标志,DF← 0
STI ;置位中断标志,DF← 1
空操作指令
NOP
?不执行任何操作, 但占用一个字节存
储单元, 空耗一个指令执行周期
?NOP常用于程序调试
? 在需要预留指令空间时用 NOP填充
? 代码空间多余时也可以用 NOP填充
? 还可以用 NOP实现软件延时
?事实上, NOP和 XCHG AX,AX的指令
代码一样, 都是 90H
NOP
段超越前缀指令
?在允许段超越的存储器操作数之
前, 使用段超越前缀指令, 将采
用指定的段寄存器寻址操作数
CS,;使用代码段的数据
SS,;使用堆栈段的数据
DS,;使用数据段的数据
ES,;使用附加段的数据
封锁前缀指令
LOCK ;封锁总线
?这是一个指令前缀, 可放在任何
指令前
?这个前缀使得在这个指令执行时
间内, 8086 处理器的封锁输出引
脚有效, 即把总线封锁, 使别的
控制器不能控制总线;直到该指
令执行完后, 总线封锁解除
暂停指令
HLT ;进入暂停状态
?暂停指令使 CPU进入暂停状态, 这时
CPU不进行任何操作 。 当 CPU发生复
位或来自外部的中断时, CPU脱离暂
停状态
?HLT指令可用于程序中等待中断 。 当
程序中必须等待中断时, 可用 HLT,
而不必用软件死循环 。 然后, 中断使
CPU脱离暂停状态, 返回执行 HLT的
下一条指令
交权指令
ESC 6位立即数,reg/mem;把浮点指令交给浮点处理器执行
?浮点协处理器 8087指令是与 8086的整数指令组合
在一起的, 当 8086发现是一条浮点指令时, 就利
用 ESC指令将浮点指令交给 8087执行
?实际编写程序时, 一般采用易于理解的浮点指令
助记符格式
ESC 6,[SI];实数除法指令,FDIV dword ptr [SI]
ESC 20H,AL;整数加法指令,FADD ST(0),ST
等待指令
WAIT ;进入等待状态
?8086利用 WAIT指令和测试引脚实现与
8087同步运行
?浮点指令经由 8086处理发往 8087,并
与 8086本身的整数指令在同一个指令
序列;而 8087执行浮点指令较慢, 所
以 8086必须与 8087保持同步
第 5章 总结
?本章详细而完整地介绍了 8086的 16位
指令系统的每条指令
?希望大家进行一下整理 ( 总结 ),
? 寻址方式
? 指令支持的操作数形式
? 指令对标志的影响
? 常见编程问题
?通过复习整理, 形成指令系统的整体
概念, 进而掌握常用指令
第 5章 教学要求 ( 5)
1,掌握基本指令,JMP/ Jcc,JCXZ/ LOOP、
CALL/ RET,INT n
2,熟悉特色指令,IRET,NOP
3,了解不常使用的指令,LOOPZ/ LOOPNZ、
INTO,LOCK/ HLT/ ESC/ WAIT
4,习题 4( p73)
2.32 2.34 2.36 ⑶ ⑹ ⑺
2.39 2.44
课间休息