1、第 4 章 程序设计方法4.1 概述4.1.1 汇编语言程序设计的一般步骤汇编语言程序设计一般有以下几个步骤:1.分析问题,确定算法2. 绘制流程图3. 根据流程图编制程4. 分配存储器和寄存器5写源程序6调试程序4.1.2 流程图1流程图的概念 流程图是由特定的几何图形、指向线、文字说明来表示数据处理的步骤,形象描述逻辑控制结构以及数据流程的示意图。流程图具有简洁、明了、直观的特点。2流程图符号表示(1)起止框:表示程序的开始和结束。 (2)判断框(3)处理框 (4)调用框 (5)指向线 (6)连接框 4.2 顺序程序设计下面举例说明顺序程序的设计。【例 4.1】试编写一程序计算以下表达式的
2、值。=(v-(*+-540) )/x式中 x、v 均为有符号字数据。设、的值存放在字变量、V 中,结果存放在双字变量之中,程序的流程图如图4.1 所示。源程序如下:DATA SEGMENTX DW 200Y DW 100Z DW 3000V DW 10000W DW 2 DUP(?)DATA ENDSSTACK SEGMENT STACKDB 200 DUP(0)STACK ENDSCODE SEGMENTASSUME DS:DATA,CS:CODE,SS:STACKSTART: MOV AX,DATAMOV DS,AX ;DATAAXMOV AX,X IMUL Y ;(X)*(Y)DX:AX
3、MOV CX,AXMOV BX,DX ;(DX:AX)(BX:CX)MOV AX,ZCWD ;(Z)符号扩展 ADD CX,AXADC BX,DX ;(BX:CX)+(DX:AX)(BX:CX)SUB CX,540SBB BX,0 ;(BX:CX)-540(BX:CX)MOV AX,V CWD ;(V)符号扩展 SUB AX,CXSBB DX,BX ;(DX:AX)-(BX:CX)(DX:AX)IDIV X ;(DX:AX)/XMOV W,AX ;商WMOV W+2,DX ;余数 DXW+2MOV AH,4CHINT 21HCODE ENDS ;退出 DOS 状态 END START【例 4.
4、2】已知某班学生的英语成绩按学号(从 1 开始)从小到大的顺序排列在 TAB 表中,要查的学生的学号放在变量 NO 中,查表结果放在变量ENGLISH 中。编写程序如下:STACK SEGMENT STACKDB 200 DUP(0)STACK ENDSDATA SEGMENTTAB DB 80,85,86,71,79,96DB 83,56,32,66,78。84NODB 10ENGLIST DB?DATA ENDSCODE SEGMENTASSUME DS:DATA,SS:STACK,CS:CODEBEGIN: MOV AX,DATAMOV DS ,AXLEA BX,TAB MOV AL,N
5、ODEL ALXLAT TABMOV ENGLISH,ALMOV AH,4CHINT 21HCODE ENDSEND BEGIN4.3 3 分支程序设计4.3.1 用条件转移指令实现程序分支【例 4.3】编写计算下面函数值的程序:1 X0Y= 0 X=0-1 X0设输入数据为 X、输出数据 Y,且皆为字节变量。程序流程图如图 4.2 所示。程序如下:DATA SEGMENTX DB -10Y DB ?DATA ENDSSTACK SEGMENT STACKDB 200 DUP(0)STACK ENDSCODE SEGMENTASSUME DS:DATA,SS:STACK,CS:CODESTAR
6、T: MOV AX,DATAMOV DS,AXCMP X,0 ;与 0 进行比较 JGE A1 ;X0 转 A1MOV Y,-1 ;X 0 时,-1YJMP EXITA1: JG A2 ;X0 转 A2MOV Y,0 ;X=0 时,0YJMP EXITA2: MOV Y,1 ;X0,1Y EXIT: MOV AH,4CHINT 21H CODE ENDSEND START【例 4.4】试编一程序,求三个带符号字数据中的最大值,并将最大值存入 MAX 字单元中。 设三个带符号数分别在三个字变量 X、Y、Z 中存储。程序流程图如图 4.3 所示 程序如下:STAC SEGMENT STACKDB
7、200 DUP(0)STACK ENDSDATA SEGMENTX DW 00ABHY DW 5Z DW 200MAX DW ?DATA ENDSCODE SEGMENTASSUME DS:DATA,SS:STACK,CS:CODE START: MOV AX,DATAMOV DS,AXMOV AX,XCMP AX,Y ;XY? JG L1MOV AX,Y ;YZ?CMP AX,ZJG EXITL2: MOV AX,ZJMP EXITL1: CMP AX,Z ;XZ? JLE L2EXIT: MOV MAX,AXMOV AH,4CHINT 21HCODE ENDSEND START4.3.2
8、用跳转表实现多路分支【例 4.5】设某程序有 8 路分支,试根据给定的 N 值(18) ,将程序的执行转移到其中的一路分支。 程序流程如图 4.4 所示。 程序如下:DATA SEGMENTTAB DW P1,P2,P3,P4,P5,P6,P7,P8N DB 5DATA ENDSSTACK SEGMENTDB 200 DUP(0)STACK ENDSCODE SEGMENTASSUME DS:DATA,SS:STACK,CS:CODE START: MOV AX,DATAMOV DS,AX MOV AL,NDEL ALADD AL,ALMOV BM,ALMOV BH,0JMP TABBXP1:
9、 JMP EXITP2: JMP EXITP2: JMP EXITP3: JMP EXITP8: EXIT: MOV AH,4CHINT 21HCODE ENDSEND START上述程序中的无条件转移指令的转移地址采用的是变址寻址。同理,转移地址也可以用寄存器间接寻址或基址加变址寻址,读者可自行考虑。4.4 循环程序设计4.4.1 循环程序的结构1初始化部分 2循环体部分 3循环控制部分4.4.2 单重循环程序设计1 计数控制【例 4.7】已知有几个元素存放在以 BUF 为首址的字节存贮区中,试统计其中正元素的个数。 显然,每个元素为一个 8 位有符号二进制数,统计其中正元素的个数可用循环程
10、序实现。其程序流程图如图 4.6 所示。2条件控制 【例 4.9】试编一个程序将字单元 BUF 中所含 1 的个数存入 COUNT 单元中。要测出 BUF 字单元所含 1 的个数,首先将 BUF 中的数送给寄存器 AX,然后将 AX 寄存器逻辑左移一次,如果 CF=1,则表明 AX 中的最高位为 1,则计数器 CL 计数 1 次,如果 CF=0,表明 AX 最高位为 0,这样依次将最高位移入 CF 中去测试。移位之后,判断 AX 的值是否为 0,如果为 0 则结束循环,不为 0,则继续循环。其流程图如图 4.8 所示。程序如下:STACK SEGMENT STACKDB 200 DUP(0)S
11、TACK EDNSDATA SEGMENTBUF DW 0011110010101011BCOUNT DB ?DATA ENDSCODE SEGMENTASSUME DS:DATA,CS:CODE,SS:STACK START: MOV AX,DATAMOV DS,AXMOV AX,BUFMOV CL,0 ;计数器为 0COPA: AND AX,AXJE EXIT ;(AX)=0,结束循环SHL AX,1 ;AX 左移一位 JNC LOPAINC CL ;产生进位, (CL)+1CLJMP LOPAEXIT: MOV COUNT,CLMOV AH,4CHINT 21HCODE ENDSEND
12、START4.4.3 多重循环程序设计【例 4.10】在以 BUF 为首址的字存储区中存放有 N 个有符号数,现需将它们按大到小的顺序排列在 BUF 存储区中,试编写其程序。我们采用冒泡排序算法从第一个数开始依次对相邻两个数进行比较,如次序对,则不交换两数位置;如次序不对则使这两个数交换位置。可以看出,第一遍需比较(N-1)次,此时,最小的数已经放到了最后;第二遍比较只需考虑剩下的(N-1)个数,即只需比较(N-2)次;第三遍只需比较(N-3)次,整个排序过程最多需(N-1)遍。如下面的 4 个数即是采用冒泡排序比较的例子。数 10 8 16 90 32第一遍 10 16 90 32 8第二遍 16 90 32 10 8第三遍 90 32 16 10 8程序流程图如图 4.9 所示。