第四章 程序设计技巧汇编语言的程序设计是使用计算机系统的指令或伪指令语句,组成求解不同问题,实现不同算法所需的完整序列的一个工作过程。汇编语言的程序设计方法一般包含顺序、分支、循环、子程序和宏等基本方法。
进一步学习指令、伪指令的使用。
掌握汇编语言顺序、分支、循环程序的设计方法。
子程序的设计与调用。
宏结构的设计与调用。
中断程序的设计。
I/O程序的设计。
模块程序的设计。
4.1 顺序程序结构形式
顺序程序又称作简单程序。指无分支、
无循环、无转移的程序。它一般是根据算法编出的完全顺序执行的程序。虽然实际应用的程序比它复杂的多,但它是构成程序的基础,它的质量直接影响整个程序的质量,为此如何充分利用硬件资源,合理地选择指令是编制简单程序,
提高整个程序质量的关键。
.MODEL SMALL
.STACK 256
.DATA
BCD_BUF DB 79H
ASC_BUF DB 2 DUP (?)
.CODE
.STARTUP
MOV AL,BCD_BUF
MOV BL,AL
MOV CL,4
SHR AL,CL
ADD AL,30H
MOV ASC_BUF,AL
AND BL,0FH
ADD BL,30H
MOV ASC_BUF+1,BL
.EXIT 0
END
4.2 分支程序
分支结构就是按照某种判断条件,从两个或两个以上的程序段中选择一个执行。
分支结构具有两种形式:双分支结构和多分支结构判断条件?
分支程序段
YES
NO
判断条件?
分支程序段1 分支程序段2
YESNO
条件控制伪指令
条件控制伪指令的格式
.IF 条件表达式
.分支体 1
[.ELSEIF条件表达式
.分支体 2~N-1
.]
[.ELSE
,分支体 N
.]
.ENDIF
.MODEL SMALL
.STACK
.DATA
X DW -78
Y DW 7865
RESULT DW?
.CODE
.STARTUP
MOV AX,X
SUB AX,Y
JGE GREATERZERO ; AX≥Y?,跳转
NEG AX ;求补,得到副值
GREATERZERO:
MOV RESULT,AX
.EXIT 0
END
.MODEL SMALL
.STACK
.DATA
_A SBYTE 39 ;有符号方式定义
_B SBYTE -43H
_C SBYTE 110
TAG DB?
.CODE
.STARTUP
MOV AL,_B
IMUL AL
MOV BX,AX ; BX← B2
MOV AL,_A
IMUL _C
MOV CL,2
SAL AX,CL ; AX← 4AC
.IF SWORD PTR BX>=AX
MOV TAG,0
.ELSEIF
MOV TAG,1
.ENDIF
.EXIT 0
END
双分支程序设计
通常双分支程序是根据条件是否成立,
从两个分支程序中选择其中一个分支程序去执行。双分支程序设计可用一条条件转移指令来实现,也可以用,IF-
.ELSEIF-.ENDIFT条件控制伪指令来设计,
这是分支程序设计的最基本方法。
(1) 产生条件在进行条件判断之前,必须要有先行指令产生条件。产生条件的指令为执行结果影响标志位的指令,如算术运算指令、位操作指令、串比较串扫描指令等,最常用的指令为
CMP/TEST/AND/SCASB/CMPSB。
(2) 判断条件判断条件用条件转移指令 JZ/JNZ,JC/JNC等共计 19条,我们应选择合适的条件转移指令之一完成。
(3) 定向按条件成立与否确定转移方向。
(4) 标号对每个分支程序,一定要给出标号,以确定分支后的转移地址。
注意,根据条件成立与否,两个分支之程序段,只能现在选择其中之一执行。
.MODEL SMALL
.STACK
.DATA
X DB 56
Y DB 78
Z DB 99
F1 DB?
.CODE
.STARTUP
MOV AL,X
MOV BL,AL
ADD AL,Y
JNC DO1 ;若无进位则转 DO1
ADD BL,Z
JMP QUIT
DO1,
SUB BL,Z
MOV F1,BL
QUIT:
.EXIT 0
END
4.3 循环程序
循环程序一般包括以下五个部分,
(1) 初始化部分:为循环做准备工作。
如设置地址指针 (BX/SI/DI/BP),计数器
(CL/CH/CX)及数据寄存器( AL/AX/DX)
的初值等。
(2) 循环工作部分:即循环体部分。它是循环程序的主体,用来完成循环的基本操作。
(3) 修改部分:为循环参数做必要的修改,如地址指针 (BX/SI/DI/BP),计数器 (CL/CH/CX)的值,
为下一次执行循环体做好准备。
(4) 循控部分:根据循环条件来判断、控制循环的继续或终止。
(5) 结束部分:主要是对循环的结果进行必要的处理,如将结果送入某一寄存器或内存区域。
初始化部分循环体修改部分循控部分开始结束开始初始化部分修改部分循控部分处理结果结束循环体循环控制指令及伪指令
循环控制指令 LOOP/LOOPZ/LOOPE/LOOPNZ/LOOPNE/JCXZ
注意,在执行此类重复控制指令前必须把重复次数送入寄存器 CX中
串操作指令
高级循环控制伪指令
其它循环控制指令
DEC和 JZ/JNZ指令配合。
CMP和 JZ/JNZ; JC/JNC; JO/JNO等指令配合。
AND/OR/XOR/TEST和 JZ/JNZ; JC/JNC; JO/JNO
等 指令配合。
循环程序设计方法
计数控制法。
这种程序设计方法直观,方便,但必须在循环次数已知的条件下才能采用。
计数控制法有正计数控制法和倒计数控制法,在汇编语言程序设计中一般采用倒计数控制法来设计程序。
求 1~100之间的累加和,放在 sum字单元
.MODEL SMALL
.STACK
.DATA
SUM DW?
.CODE
.STARTUP
XOR AX,AX
MOV CX,100
NEXT,
ADD AX,CX
LOOP NEXT
MOV SUM,AX
.EXIT 0
END
条件控制型循环程序设计
在实际工作中,有时循环次数无法事先确定,但循环次数与问题中的某些条件有关,这时就应根据给定的条件满足与否来判断是否结束循环。
逻辑尺控制法该方法用于特殊循环程序的设计,要处理的问题有两种,我们分别用,1”和
,0”来表示,处理的次数用,1”或,0”的个数来表示。设计程序的关键就是把处理的问题转换为由,1”和,0”组成的二进制数串。
进一步学习指令、伪指令的使用。
掌握汇编语言顺序、分支、循环程序的设计方法。
子程序的设计与调用。
宏结构的设计与调用。
中断程序的设计。
I/O程序的设计。
模块程序的设计。
4.1 顺序程序结构形式
顺序程序又称作简单程序。指无分支、
无循环、无转移的程序。它一般是根据算法编出的完全顺序执行的程序。虽然实际应用的程序比它复杂的多,但它是构成程序的基础,它的质量直接影响整个程序的质量,为此如何充分利用硬件资源,合理地选择指令是编制简单程序,
提高整个程序质量的关键。
.MODEL SMALL
.STACK 256
.DATA
BCD_BUF DB 79H
ASC_BUF DB 2 DUP (?)
.CODE
.STARTUP
MOV AL,BCD_BUF
MOV BL,AL
MOV CL,4
SHR AL,CL
ADD AL,30H
MOV ASC_BUF,AL
AND BL,0FH
ADD BL,30H
MOV ASC_BUF+1,BL
.EXIT 0
END
4.2 分支程序
分支结构就是按照某种判断条件,从两个或两个以上的程序段中选择一个执行。
分支结构具有两种形式:双分支结构和多分支结构判断条件?
分支程序段
YES
NO
判断条件?
分支程序段1 分支程序段2
YESNO
条件控制伪指令
条件控制伪指令的格式
.IF 条件表达式
.分支体 1
[.ELSEIF条件表达式
.分支体 2~N-1
.]
[.ELSE
,分支体 N
.]
.ENDIF
.MODEL SMALL
.STACK
.DATA
X DW -78
Y DW 7865
RESULT DW?
.CODE
.STARTUP
MOV AX,X
SUB AX,Y
JGE GREATERZERO ; AX≥Y?,跳转
NEG AX ;求补,得到副值
GREATERZERO:
MOV RESULT,AX
.EXIT 0
END
.MODEL SMALL
.STACK
.DATA
_A SBYTE 39 ;有符号方式定义
_B SBYTE -43H
_C SBYTE 110
TAG DB?
.CODE
.STARTUP
MOV AL,_B
IMUL AL
MOV BX,AX ; BX← B2
MOV AL,_A
IMUL _C
MOV CL,2
SAL AX,CL ; AX← 4AC
.IF SWORD PTR BX>=AX
MOV TAG,0
.ELSEIF
MOV TAG,1
.ENDIF
.EXIT 0
END
双分支程序设计
通常双分支程序是根据条件是否成立,
从两个分支程序中选择其中一个分支程序去执行。双分支程序设计可用一条条件转移指令来实现,也可以用,IF-
.ELSEIF-.ENDIFT条件控制伪指令来设计,
这是分支程序设计的最基本方法。
(1) 产生条件在进行条件判断之前,必须要有先行指令产生条件。产生条件的指令为执行结果影响标志位的指令,如算术运算指令、位操作指令、串比较串扫描指令等,最常用的指令为
CMP/TEST/AND/SCASB/CMPSB。
(2) 判断条件判断条件用条件转移指令 JZ/JNZ,JC/JNC等共计 19条,我们应选择合适的条件转移指令之一完成。
(3) 定向按条件成立与否确定转移方向。
(4) 标号对每个分支程序,一定要给出标号,以确定分支后的转移地址。
注意,根据条件成立与否,两个分支之程序段,只能现在选择其中之一执行。
.MODEL SMALL
.STACK
.DATA
X DB 56
Y DB 78
Z DB 99
F1 DB?
.CODE
.STARTUP
MOV AL,X
MOV BL,AL
ADD AL,Y
JNC DO1 ;若无进位则转 DO1
ADD BL,Z
JMP QUIT
DO1,
SUB BL,Z
MOV F1,BL
QUIT:
.EXIT 0
END
4.3 循环程序
循环程序一般包括以下五个部分,
(1) 初始化部分:为循环做准备工作。
如设置地址指针 (BX/SI/DI/BP),计数器
(CL/CH/CX)及数据寄存器( AL/AX/DX)
的初值等。
(2) 循环工作部分:即循环体部分。它是循环程序的主体,用来完成循环的基本操作。
(3) 修改部分:为循环参数做必要的修改,如地址指针 (BX/SI/DI/BP),计数器 (CL/CH/CX)的值,
为下一次执行循环体做好准备。
(4) 循控部分:根据循环条件来判断、控制循环的继续或终止。
(5) 结束部分:主要是对循环的结果进行必要的处理,如将结果送入某一寄存器或内存区域。
初始化部分循环体修改部分循控部分开始结束开始初始化部分修改部分循控部分处理结果结束循环体循环控制指令及伪指令
循环控制指令 LOOP/LOOPZ/LOOPE/LOOPNZ/LOOPNE/JCXZ
注意,在执行此类重复控制指令前必须把重复次数送入寄存器 CX中
串操作指令
高级循环控制伪指令
其它循环控制指令
DEC和 JZ/JNZ指令配合。
CMP和 JZ/JNZ; JC/JNC; JO/JNO等指令配合。
AND/OR/XOR/TEST和 JZ/JNZ; JC/JNC; JO/JNO
等 指令配合。
循环程序设计方法
计数控制法。
这种程序设计方法直观,方便,但必须在循环次数已知的条件下才能采用。
计数控制法有正计数控制法和倒计数控制法,在汇编语言程序设计中一般采用倒计数控制法来设计程序。
求 1~100之间的累加和,放在 sum字单元
.MODEL SMALL
.STACK
.DATA
SUM DW?
.CODE
.STARTUP
XOR AX,AX
MOV CX,100
NEXT,
ADD AX,CX
LOOP NEXT
MOV SUM,AX
.EXIT 0
END
条件控制型循环程序设计
在实际工作中,有时循环次数无法事先确定,但循环次数与问题中的某些条件有关,这时就应根据给定的条件满足与否来判断是否结束循环。
逻辑尺控制法该方法用于特殊循环程序的设计,要处理的问题有两种,我们分别用,1”和
,0”来表示,处理的次数用,1”或,0”的个数来表示。设计程序的关键就是把处理的问题转换为由,1”和,0”组成的二进制数串。