1
4.2.4 过程定义伪指令 PROC,ENDP
过程就是子程序。一个过程可以被其它程序所调
用 (用 CALL指令 ),过程的最后一条指令一般是返回
指令 (RET)。
过程定义伪指令的格式为
<过程名 > PROC [类型 ]


RET
<过程名 > ENDP
注意,PROC和 ENDP必须成对出现 。
2
过程的类型有两种:
NEAR——(默认类型 )表示段内调用
FAR——表示段间调用
调用一个过程的格式为:
CALL <过程名 >
3
4.2.5 宏定义伪指令
如果需要多次使用同一个程序段,可以
将这个程序段定义为一个,宏 指令”,
然后 在 需要时,可简单地用 宏指令名 来
代替这个程序段。
指令的格式为:
<宏指令名 > MACRO [形参表 ]
<宏定义体 >
ENDM
4
例,两个数之和的宏定义和宏调用 。
宏定义为:
DADD MACRO X,Y,Z
MOV AX,X
ADD AX,Y
MOV Z,AX
ENDM
X,Y,Z是形式参数。调用宏 DADD时可写为:
DADD DATA1,DATA2,SUM
DATA1,DATA2,SUM是实际参数,由 它们替
换定义中的 X,Y,Z。
5
宏调用与过程 (子程序 )调用 都是一次定义,多次调
用 。 它们之间的差别是:
① 执行形式, 宏命令伪指令由宏汇编程序 在汇编过
理中进行处理, 而 CALL,RET则是 由 CPU执行的
指令 。
② 汇编结果, 宏命令伪指令 汇编后被展开。
③ 执行速度, 宏命令 执行速度较快 (因无调用转移 )
④ 占用内存, 宏指令简化了源程序,但不能简化目
标程序, 并不节省内存单元。 使用过程可以节省代
码占用的内存空间。
6
宏展开:汇编程序会把宏调用按宏定义展开。
例如:宏定义为:
Display MACRO string
LEA DX,string
MOV AH,9
INT 21H
ENDM
程序中宏调用:
……
DISPLAY ERROR_MESSAGE
DISPLAY EXIT_MESSAGE
……
汇编后的结果,(带有 +号的指令为宏展开后的结果 )
……
+ LEA DX,ERROR_MESSAGE
+ MOV AH,9
+ INT 21H
+ LEA DX,EXIT_MESSAGE
+ MOV AH,9
+ INT 21H
……
7
4.2.6 汇编结束伪指令 END
汇编语言源程序的最后, 要加 汇编结束
伪指令 END,以使汇编程序结束汇编。
格式,END [表达式 ]
END后跟的表达式通常就是程序第一条
指令的标号,指示程序的启动地址 (要
执行的第一条指令的地址 )。
8
汇编语言的一个实例:
EXAM.ASM
9
4.3 DOS系统功能调用介绍
? 系统功能调用 —— 由 OS提供的一组实现特殊功能
的子程序供程序员在程序中调用,以减轻编程工
作量。
? 系统功能调用有两种,一种称为 DOS功能调用,
另一种称为 BIOS功能调用。
? 用户程序在调用这些系统服务程序时,不是用
CALL命令,而是采用软中断指令 INT n来实现。
? 在 DOS系统 中,功能调用都是用软中断指令 INT
21H来实现的。
10
INT 2lH功能大致可以分为四个方面:
设备管理、目录管理、文件管理和其它。
参见 P411页附录 C.3
D0S系统功能调用的使用方法如下:
① AH← 功能号 ;
② 设置该功能所要求的其他入口参数;
③ 执行 INT 21H指令;
④ 分析出口参数 。
以下 介绍 INT 21H的几个最常用的功能 。
11
关于数据输入和输出我们这里只讨
论 键盘输入 和 显示输出,调用系统功能
需要提供入口参数及所调用的功能号,
调用结束返回结果。
1,DOS键盘功能调用
(1) 从键盘输入一个字符 (功能号 =1)
MOV AH,1
INT 21H
<AL中有键入的字符 >
12
例,程序中有时需要用户对提示做出应答。
GET_KEY,MOV AH,1 ;等待键入字符
INT 21H ;结果在 AL中
CMP AL,’Y’ ;是 ’ Y’?
JZ YES ;是,转 YES
CMP AL,’N’ ;是 ’ N’?
JZ NO ;是,转 NO
JMP GET_KEY ;否则继续等待输入
YES,…

NO,…
13
(2) 输入字符串 (功能号 =0AH)
此功能调用从键盘输入一串字符并把它
存入用户指定的缓冲区中。
MOV AH,0AH
LEA DX,<字符串缓冲区首地址 >
INT 21H
(预留的 N1个字节的存储单元 ) 0DHN2N1
N1,缓冲区长度 (最大键入字符数 )
N2,实际键入的字符数 (不包括回车符 )
用户定义的输入字符串的缓冲区格式
14
若用户键入的字符数 (包括回车 )≥ 定义的
N1,本功能调用将不再接收新的键入,且光
标不再向右移动。
例:设在数据段定义键盘缓冲区如下:
STR1 DB 10,?,10 DUP(?)
调用 DOS功能的 0AH号功能的程序段为:
LEA DX,STR1
MOV AH,0AH
INT 21H
此程序段最多从键盘接收 10个按键(包
括回车)。
15
2,DOS显示功能调用
(1) 在显示器上显示一个字符 (功能号 =2)
MOV AH,2
MOV DL,<要显示的字符 >
INT 21H
例:在显示器上显示一个字符 ‘ A’
MOV AH,2
MOV DL,’A’ ;或 MOV DL,41H
INT 21H
16
MOV AH,9
LEA DX,<字符串 >
INT 21H
注意:被显示的字符串必须以 ’ $’ 结束 。
(2)显示字符串 (功能号 =9)
17
例,在屏幕上显示,’ HELLO,WORLD!’;在数据段定义字符串:
DATA SEGMENT
STR1 DB ‘HELLO,WORLD!$’
DATA ENDS;在代码段中进行显示输出
MOV AH,9
LEA DX,STR1
INT 21H
完整的程序, HELLO.ASM
18
附,BIOS功能调用
BIOS:基本输入输出系统,是固化在 EPROM中的一组实
现基本输入输出功能的子程序。
BIOS调用通过多个软中断提供,调用方法为,
MOV AH,<功能号 >
<设置入口参数,一般将参数放在寄存器中 >
INT <中断类型 >
BIOS中的几个主要中断类型如下:
INT 10H——屏幕显示
INT 13H——磁盘操作
INT 14H——串行口操作
INT 16H——键盘操作
INT 17H——打印机操作
每类中断由包含许多子功能,调用时通过功能号指定。
BIOS功能调用说明见 p416附录 D。
19
4.4 汇编语言程序设计基础
4.4.1 概述
1.程序质量 (自学 )
2.汇编语言程序设计的步骤:
1-根据实际问题抽象出数学模型,确定算法
2-画出程序框图 (流程图 )
3-分配内存工作单元和寄存器
4-根据框图编写源程序,存成,ASM文件
5-对源程序汇编, 生成,OBJ目标文件
6-把,OBJ文件连接成,EXE执行文件
7-运行, 调试
3.源程序的基本结构:顺序, 分支, 循环, 过程
20
(1)用方框表示工作框,框中用简明语言
标明要完成的功能
(2) 用菱形框表示判断框
框中标明比较、判断和条件
如何绘制程序框图 (流程图 )?
N
Y
21
(4)各框之间用直线连起来表示程序走向。
框中标明 子程序名字 (入口参数等 )
(3)用 框表示调用子程序或过程 。
流程图的例子 FlowChart.doc
22
汇编语言上机过程
Y
Y
Y
N
N
N
有错?
有错?
有错?
结束
汇 编
输入 (修改 )源程序
连 接
运 行
查 错
开始
用 EDIT,NOTEPAD等任何文本
编辑器。源程序存为,ASM文件
用 MASM宏汇编程序进行汇编。
汇编后生成,OBJ目标文件。
命令格式,MASM <源文件名,ASM>;
用 LINK连接程序进行连接。
连接后生成,EXE可执行文件。
命令格式,LINK <目标文件名,OBJ>;
用 TD,DEBUG等调试程序进行调试。
命令格式,TD <可执行文件名,EXE>
23
标号,
条件满足

处理
4.4.2 顺序程序 (p175-176,自学 )
4.4.3 分支程序
N
Y
IF…THEN 结构
程序结构:

测试 /比较指令 (TEST/CMP)
条件转移指令 (Jx 标号 )
处理体
标号, 其他指令

24
程序结构:
TEST/CMP指令
Jx 标号 1
处理体 P1
JMP 标号 2
标号 1:
处理体 P2
标号 2:其他指令

条件满足

处理 P1 处理 P2
标号 1:
标号 2:
条件 1 条件 2
IF…THEN…ELSE 结构
25
标号 1:
条件 1成立
? P1
N
Y
CASE结构 程序结构:

TEST/CMP指令(测试条件 1)
Jx 标号 1 ;不满足转标号 1
处理体 P1…
JMP 标号 n+1
标号 1,TEST/CMP指令(测试条件 2)
Jx 标号 2 ;不满足转标号 2
处理体 P2…
JMP 标号 n+1
标号 2,TEST/CMP指令(测试条件 3)
Jx 标号 3 ;不满足转标号 3
处理体 P3…
JMP 标号 n+1
标号 3,TEST/CMP指令(测试条件 4)


标号 n+1:(公共出口)
条件 2成立

条件 n成立


Pn+1
标号 2:
标号 n:
标号 n+1:
P2
Pn
N
N
Y
Y
例,P178,[例 4-14],统计成绩。 流程图中虚线框内
26
4.4.4 循环程序
1,DO…UNTIL< 条件 > 结构
先执行,再判断条件。工作部分至少执行
一次。
初始化
循环体
循环控制
继续循环? Y
N
27
2,DO WHILE<条件 > 结构
先判断条件,再执行。工作部分有可能一
次都不执行。
初始化
循环体
循环控制
继续循环? Y
N
28
注意:循环可以嵌套 (多重循环 ),但多个循环
体之间不能交叉,控制条件不能混淆。
例,P179[例 4-15],数据从大到小排序。
冒泡法 —— 实例,3,7,2,8,6→8,7,6,3,2 。
?内外两层循环;
?每轮内循环使一个最小的数沉底,因为最小的
数沉底,下轮内循环就不用再比较最底下的数,
所以内循环的循环次数每一轮比上一轮要逐次
减 1;
?外循环用于控制有多少轮内循环。若有 n个数
据,则外循环次数为 n-1。
BSORT.ASM
29
掌握以下几点,
?调用子程序用 CALL指令, 返回调用程序用 RET指
令 。
?子程序允许嵌套调用 。
?进入子程序后首先要保护主程序的运行状态 (标
志位 )和使用的寄存器内容 (称为 保护现场 ),退
出子程序前要 恢复现场 。
?调用前要预先确定子程序中要 使用哪些寄存器,
并 定义入口参数和出口参数 。 参数传递可利用
寄存器, 存储单元或堆栈 ( 要用 BP寻址 ) 。
4.4.5 子程序设计举例
30
例 1,二进制数 (0-F)转换成 ASCII(‘0’-‘F’)的子程序 。
BIN2ASC PROC;要转换的数在 AL的低四位;转换结果仍在 AL中
CMP AL,9
JA A2F
ADD AL,30H
JMP DONE
A2F,ADD AL,37H
DONE,RET
BIN2ASC ENDP
调用方法,( 在主程序中 )

MOV AL,0CH
CALL BIN2ASC
(AL中有 0CH的 ASCII码 43H,’C’)
31
例 2,字符串处理程序设计
此例取自 p182[例 4-17]。
对字符串进行操作时,往往需要确定它的长
度。通常字符串结束标志以 CR或 $作标志。所
以可以用扫描 CR或 $的方法计算出串长。
在计算串长时,应注意串长一般应小于 255
个字节。
以下是流程图和源程序。
32
简化的流程图:
开始
求串长
串长 <256?
显示串长高位
显示串长低位
结束
Y 警告, 太长
求串长
当前字符是‘$’?
搜索 CR字符
同时指针增量
返回
N
串长加 1
存串长
N
找到? N
Y
Y
初始化指针 /计数器
33
程序如下:
DATA SEGMENT
STRING DB ‘This is a string…’,0DH,’$’
LENGTH1 DW? ;串长度存放在这里
CR DB 0DH
MESSAGE DB ’The string is too long!’,0DH,0AH,’$’
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
MAIN PROC FAR
BEGIN,MOV AX,DATA
MOV ES,AX
MOV DS,AX
34
CALL STRLEN ;调用子程序计算串长
MOV DX,LENGTH1 ;结果在 DX寄存器中
CMP DX,100H
JB NEXT1 ;若 (DX)< 100H,转
LEA DX,MESSAGE ;若 (DX)≥ 100H,
MOV AH,9
INT 21H ;显示信息
JMP NEXT2
NEXT1,MOV DH,DL ;串长暂存在 DH中
MOV CL,4
SHR DL,CL ;取串长高 4位
CMP DL,9
35
JBE LP ;≤9,转
ADD DL,7 ;> 9,加 7
LP,ADD DL,30H ;高 4位 转换 为 ASCII码
MOV AH,6
INT 21H ;显示这个 ASCII码
MOV DL,DH ;取暂存串长
AND DL,0FH ;取串长低 4位
CMP DL,9
JBE LP1 ;≤ 9,转
ADD DL,7 ;> 9,加 7
LP1,ADD DL,30H ;低 4位转换为 ASCII码
MOV AH,6
INT 21H ;显示该 ASCII码
36
MOV DL,’H’
MOV AH,6
INT 21H ;显示 ’ H’
NEXT2,MOV AH,4CH
INT 21H ;返回 DOS
MAIN ENDP;------- 主程序结束 --------;-----计算串长的子程序 -----
STRLEN PROC
LEA DI,STRING
MOV CX,0FFFFH ;(CX)=-1
MOV AL,CR ;(AL)=0DH
MOV AH,’$’ ;(AH)=24H
CLD ;DF=0
37
AGAIN,INC CX ;串长加 1,初始值 (CX)=0
CMP CX,100H
JAE DONE ;串长 >255,则结束
CMP [DI],AH ;本字符是 ’ $’?
JE DONE ;是,则结束
SCASB ;本字符是 CR?
JNE AGAIN ;未找到,返回继续
DONE,MOV LENGTH1,CX ;找到,LENGTH1← 串长
RET ;返回主程序
STRLEN ENDP;----- 子程序结束 -----
CODE ENDS
END BEGIN
38
本例主要介绍了:
– 含有子程序的汇编语言程序结构
– 字符串的处理 ——如何计算字符串长度
– 如何把二进制数转换成 ASCII显示在屏幕上