第 5 章 程序设计及汇编语言内容安排一,程序设计步骤二,程序设计三,汇编语言及汇编程序四,汇编语言源程序格式及实例五,上机操作
§ 5.1 程序设计步骤
( 1)分析问题
( 2)建立数学模型
( 3)确定算法
( 4) 绘制程序流程图
( 5) 内存空间分配
( 6)编制程序与静态检查
( 7)程序调试(实验)
开始结束处理处理处理分支是否
§ 5.2 程序设计特点,计算机执行程序的方式是“从头到尾”逐条执行指令语句,直至程序结束
1,简单 程序例 5-1:用数据运算指令,对两个 16位数做加法运算。这两个数从地址 10050H开始连续存放,低位在小地址一端,结果存放在这两个数之后流程图,
开始暂停
AX 10054H和 10055H单元被加数 +加数 AX
初始化加数 AX
MOV AX,1000H
MOV DS,AX ; DS= 1000H
MOV SI,50H ;被加数指针 SI= 50H
MOV DI,52H ;加数指针 DI= 52H
MOV BX,54H ;和的指针 BX= 54H
CLC ;清 CF
XOR AX,AX ;清 AX
MOV AX,[SI] ;取一个字到 AX
ADC AX,[DI] ; AX←AX + [DI]+CF
MOV [BX],AX ;存一个字到 [BX]
HLT ;暂停程序,
例 5-2:将内存 10050H单元的内容拆成两段,
每段 4位,并将它们分别存入内存 10051H和
10052H单元。即
10050H单元中的低 4位放入 10051H的低 4位,
10050H单元中的高 4位放入 10052H的低 4位,
而 10051H和 10052H的高 4位均为零流程图,
开始暂停逻辑右移得高 4位,存入内存 10052H单元用逻辑与指令将该数“与” 0FH
取得低四位,存入内存 10051H单元初始化用间址方法取数 AL
再取出原始数 AL
程序,
MOV AX,1000H
MOV DS,AX ; DS= 1000H
MOV SI,50H ;需拆字节的指针 SI=50H
MOV AL,[SI] ;取一个字节到 AL中
AND AL,0FH ;把 AL的前 4位清 0
MOV [SI+1],AL ;把得到的后 4位放到 10051H单元
MOV AL,[SI] ;再取出需拆字节放到 AL中
MOV CL,4
SHR AL,CL ;逻辑右移四次,前 4位补 0
MOV [SI+2],AL ;放入 10052H单元
HLT
2,分支 程序利用条件转移指令,使程序执行到某一指令后,根据条件(即上面运算的情况)是否满足,改变程序执行的次序特点,先用比较指令、数据操作、位测指令等改变标志寄存器各个标志位,然后用条件转移指令进行分支例 5-3:求 AX累加器和 BX寄存器中两个无符号数之差的绝对值,结果放在内存 2800H单元中流程图,
开始初始化:清除C F
AX-BX AX
AX-BX ≥ 0?
AX 内存(2 8 0 0 H )和(2 8 0 1 H )单元
BX-AX BX
BX 内存(2 8 0 0 H )和(2 8 0 1 H )单元暂停是否程序,
CLC ;清除 CF
MOV CX,AX
SUB AX,BX ; AX←AX - BX,影响 CF
JC AA ; CF= 1转 AA去执行(即 AX<BX时转移)
MOV DI,2800H ;结果指针 DI= 2800H
MOV [DI],AX ;结果送到 2800H和 2801H单元
JMP LP ;暂停
AA,SUB BX,CX ; BX←BX - CX
MOV DI,2800H
MOV [DI],BX
LP,HLT
例 5-4,编制程序从外设 71H端口中取一个数 M,
判断其值是否在
10和 20之间,即
10≤M<20。如果
M≥20,则送
0FFH给外设 73H
端口;如果
M<10,则送 00H
给外设 73H;如果 10≤M<20,则送 88H给外设
73H
开始暂停输出 BL值到
73号外设去输入 71号外设的值 AL
令 BL=88H
令 BL=00H
令 BL=0FFH
AL值 ≥ 20
AL值 ≥ 10
是是否否
LP1
LP2
START,IN AL,71H ;将 71H端口的字节读入 AL
CLC ;清除 CF
CMP AL,10 ; AL←AL - 10
JC LP1 ;小于 10转 LP1
CMP AL,20 ; AL←AL - 20
JC LP2 ; 10≤AL<20转 LP2
MOV BL,0FFH ;将 FFH送入 BL寄存器
LP3,MOV AL,BL
OUT 73H,AL ;将结果的标志数据输出到 73H端口
HLT ;暂停
LP1,MOV BL,00H
JMP LP3
LP2,MOV BL,88H
JMP LP3
程序,
3,循环 程序强制 CPU重复执行某一指令系列(程序段)的一种程序结构形式组成,初始化循环体循环控制循环结束处理例 5-5,求两个多字节数之和。这两个数在 10050H地址开始的内存单元中,连续存放,低位在小地址一端,结果放在这两个数之后。设这两个多字节数均为 8个字节长流程图,开始暂停初始化 段地址 DS,1000H
SI=50H,DI=58H,BX=60H
CX=4,CF=0
和数 =前一次 +(指针)
即 AX AX+[DI]+CF
CX= 0
是否
SI SI+2
修改指针 DI DI+2
计数器 CX CX-1
取一个字 AX
程序,
START,MOV AX,1000H
MOV DS,AX
MOV SI,50H
MOV DI,58H
MOV BX,60H
MOV CX,4
CLC
AA,MOV AX,[SI]
ADC AX,[DI]
MOV [BX],AX
PUSHF
ADD SI,2
ADD DI,2
ADD BX,2
POPF
LOOP AA
HLT
例 5-6,要求设计一个软件延时程序,延时时间约 1秒左右延时时间主要取决于循环体及循环次数。从指令表上可以查得 PUSHF和 POPF指令分别为 10和 8个时钟节拍,
LOOP指令为 3.4个时钟节拍,即此循环体需要用 10+ 8+
3.4= 21.4拍,而每个时钟节拍是根据系统的晶振频率而定的。假设此系统用的是 8MHz的晶振,则每个时钟节拍需要 0.125μs,因此可以根据下列公式算出循环次数:
次一次循环时间 延时时间 3 7 4s1 2 5.04.21 ms1X
流程图,
开始
BX=3E8H(循 环值)
BX BX-1
BX=0?
暂停是否延时1 m s 程序程序,
MOV BX,3E8H
LP2,MOV CX,176H
LP1,PUSHF
POPF
LOOP LP1
DEC BX
JNZ LP2
HLT
4,子 程序
( 1)子程序设计与应用应 注意的问题
现场保护与恢复
参数传递
子程序说明
CALL
RET
( 2)子程序调用 技巧
子程序嵌套
子程序递归
可重入子程序
协同子程序例 5-7:找出一个数据块中的最大数。
其中,数据块的长度 >1,并且放在内存 2001H单元中,
而数据块本身是从
2002H单元开始存放的,最后,把找出的最大值放到
2000H单元中,假设这段数据块中的数都是无符号的 8
位数,请设计成一段可调用的子程序开始暂停
SI=2001H,CL=[SI]
00 AL,SI SI+1
修改指针 SI SI+1
是否CX CX-1
CX=0
AL [SI]
AL值 ≤ [SI]
AL [2000H]
是否
LP
程序,
MAX,PUSHF
PUSH AX
PUSH CX
PUSH SI
MOV SI,2001H
MOV CL,[SI]
INC SI
MOV AL,00H
MOV CH,00H
LP,CLC
CMP AL,[SI]
JNC AA
MOV AL,[SI]
AA,INC SI
LOOP LP
MOV [2000H],AL
POP SI
POP CX
POP AX
POPF
RET
§ 5.3 汇编语言及汇编程序汇编语言易识别,但机器不能直接执行;机器语言相反
1,汇编语言与机器语言汇编语言源程序 目标程序汇编程序汇编汇编语言程序设计的 特点,
汇编语言是面向机器的语言,CPU不同的机器有不同的汇编语言
可以充分利用机器的硬件功能和结构特点
可有效地加快程序的执行速度,减少目标程序所占用的存储空间
可以对输入 /输出端口进行控制,实时性能好
汇编语言程序移植性、通用性、可读性差汇编语言的指令 机器语言的指令一一对应汇编程序,ASM-86/MASM-86
2,伪指令语句特点,不同于指令语句,伪指令语句(又称命令语句)
中的伪指令本身 不产生 对应的机器目标代码功能,仅仅是告诉汇编程序,对后面的指令语句和伪指令语句的操作数应该如何产生机器目标代码伪指令语句 格式,
标号,指令助记符 操作数 ;注释

伪指令
3,伪指令
( 1) 符号定义 伪指令(赋值语句)
格式,<名字 > EQU <表达式 >
功能,把表达式的值赋给符号名伪指令 机器指令一一对应特点,伪指令不是由 86系列 CPU执行,而是由 MASM-86
识别,并完成相应的功能注意,用 EQU语句赋值的符号名不能被重新赋值
( 2) 内存数据定义 伪指令格式,[名字 ] DB <表达式或数据项表 >
[名字 ] DW <表达式或数据项表 >
功能,表达式或项表中的每一项是一个 /两个字节数,他们从符号名地址开始按字节连续存放,直到表中数据项结束如,D1 DB 12H,12H 12H
D1 DB 3 DUP (12H)
MOV AX,D1
注意,① 表达式或数据项表多于一项时,项与项之间用逗号“,,或 空格 分隔
② 表达式或数据项重复书写时,可用重复格式 DUP
③ 需考虑符号名的 类型一致
( 3) 段定义 伪指令格式,<段名 > SEGMENT [定位方式 ][连接方式 ][‘类别名 ’ ]

<段名 > ENDS功能,给存储器在逻辑上分段,它为程序的汇编和连接说明了段名、分段的各种属性以及分段的开始和结束定位方式,又称定位类型,指定段的起始地址边界
PAGE
PARA
WORD
BYTE
指定起始地址的 低 8位是 0
指定起始地址的 低 4位是 0
指定起始地址的 最低位是 0
指定起始地址是 任意值连接方式,又称组合类型,告诉连接程序本段与其他段可按某种方式连接
PUBLIC
STACK
空缺( NONE)
COMMON
MEMORY
AT 表达式把本 段与其他同名同类型的段连接起来,共用一个段的起点地址,形成一个物理段表示 本段是堆栈段,连接方式同 PUBLIC
表示 本段不与任何段连接,是系统隐含连接方式表示 本段与同名同类型的段共用同一段的起点地址,
即同名同类段相重叠,段的长度是最长段的长度表示 本段在连接时定位在所有段之上,即高地址处表示 本段定位在表达式值指定的段地址处类别名,需用单引号括起来,凡是类型名相同的段在连接时均按先后顺序连接起来
( 4) 段寄存器说明 伪指令格式,ASSUME 段寄存器:段定义名 1 [,段寄存器:
段定义名 2,… ]
功能,告诉汇编程序在汇编时,段寄存器 CS,DS,SS:
和 ES:应具有的 符号段基址,以便汇编指令时确定段和建立错误信息。但是段寄存器 实际值 ( CS除外)还要有传送指令在执行程序时赋值
( 5) 模块开始 伪指令格式,NAME 模块名功能,指明程序模块的开始,并指出模块名,一般取源程序文件名为模块名
( 6) 过程(子程序)定义 伪指令格式,<过程名 > PROC [NEAR] (或 [FAR])

<过程名 > ENDP
功能,定义过程是为了实现子程序调用而设的调用格式,CALL <过程名 >
过程由 RET指令返回
( 7) 模块结束 伪指令格式,END [启动标号或过程名 ]
功能,告诉汇编程序源文件结束,并给出执行程序的入口位置
( 8) 定位 伪指令格式,ORG <表达式 >
功能,把以下语句定义的内存数据或程序,从表达式指定的起点(偏移地址)开始连续存放,直至遇到新的
ORG指令。表达式值是一个 无符号数
( 9) 列表 伪指令格式,PAGE 行数,行字数功能,为列表文件定义每页行数( 10~255)和每行字符数( 60~132),默认值是 66行,80列
§ 5.4 汇编语言源程序格式及实例
DATA SEGMENT
┇ } 存放数据项的数据段
DATA ENDS
EXTRA SEGMENT
┇ } 存放数据项的附加段
EXTRA END
STACK1 SEGMENT PARA STAC
┇ } 作堆栈用的堆栈段
STACK1 ENDS
( 1) 汇编语言源程序基本格式
COSEG SEGMENT
ASSUME CS,COSEG,DS,DATA
ASSUME SS,STACK1,ES,EXTRA
BEING,MOV AX,DATA
MOV DS,AX
┇ } 存放指令序列
COSEG ENDS
END BEING
注意,排列的先后顺序可以是任意的例 5-8:从键盘上输入任意一个 1位十进制数( 0~ 9),
用移位指令乘 10,并将结果显示出来
( 2) 实例程序,
NAME EX1
PAGE 50,70
DAT SEGMENT PARA 'DAT'
BUFF DB 4 DUP(?)
DAT ENDS
STAC SEGMENT PARA STACK 'STA'
STA1 DB 100 DUP(?)
STAC ENDS
CODE SEGMENT PARA 'CODE'
ASSUME CS,CODE,DS,DAT
ASSUME SS,STAC,ES,DAT
START PROC FAR
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DAT
MOV DS,AX
LEA SI,BUFF ;建立缓冲区首址指针
CALL P1 ;调键盘输入子程序
CALL P2 ;调乘 10子程序
CALL P3 ;调显示子程序
RET;返回 DOS;设置 DS值
P1 PROC ;键盘输入子程序
RE,MOV AH,1
INT 21H
CMP AL,'0'
JC RE
CMP AL,'A'
JNC RE
AND AL,0FH
MOV [SI],AL
MOV DL,0DH
MOV AH,2
INT 21H
MOV DL,0AH
MOV AH,02H
INT 21H
RET
P1 ENDP;从键盘输入一个数并显示;判数据输入合法否?若不合法,重新输入;将输入数据转换为 BCD码存缓冲区;回车换行符送显示
P2 PROC ;乘 10子程序
MOV AL,[SI] ;从缓冲区取数
SHL AL,1
MOV BL,AL
MOV CL,2
SHL AL,CL
ADD AL,BL
MOV AH,0
MOV BL,10
DIV BL
ADD AH,30H
ADD AL,30H
MOV [SI],AL
MOV [SI+1],AH
RET
P2 ENDP;乘 10;将积转换成 ASCⅡ 码存缓冲区
P3 PROC ;显示子程序
MOV DL,[SI]
MOV AH,2
INT 21H
MOV DL,[SI+1]
MOV AH,2
INT 21H
RET
P3 ENDP
CODE ENDS
END START
§ 5.5 上机操作编辑程序,ASM MASM,OBJ
LINK
.EXE
汇编语言上机过程,
开机进行系统选择 →DOS
进入 DOS环境 C:\>
C:\> CD MASM ↙
C:\MASM> EDIT ↙
进入编辑环境,输入程序,输入完毕存盘
ALT-F →NEW 建立新文件
OPEN 打开已有文件
SAVE 保存
SAVE AS 另存为

EXIT 退出选择 SAVE ↙,命名 EX1.ASM ↙
ALT- F → EXIT
回到 DOS环境
C:\MASM> MASM EX1.ASM ↙
3次回车,无错,
0 warnings
0 errors.
C:\MASM> LINK EX1.ASM ↙
3次回车
Running,EX1.EXE,EX1↙
看结果 !
作业
1,编写出执行以下计算的程序,其中 X,Y,Z,R,W均为存放 16位带符号数单元地址
( 1)
( 2)
2,编程序,用 TEST指令测试 DL寄存器位 3,位 6是否同时为 0,若是,将 0送 DL;否则 1送 DH。
3,编一程序段,完成符号函数:
假设 x的值存放在 DATA1中,y的值存放在 DATA2中。
4,设 AX寄存器中有一个 16位二进制数,编一程序,统计 AX中,1”
的个数,统计结果送 CX中。
96 RXWZ
25 YXWZ





01
00
12712801
x
x
xx
y
5,读程序:
START,IN AL,20H
MOV BL,AL
IN AL,30H
MOV CL,AL
MOV AX,0
ADLOP,ADD AL,BL
ADC AH,0
DEC CL
JNZ ADLOP
HLT
请问:
( 1) 本程序实现什么功能?
( 2) 结果在哪里?