程序设计.doc
- 文档编号:1223948
- 上传时间:2023-04-30
- 格式:DOC
- 页数:18
- 大小:82KB
程序设计.doc
《程序设计.doc》由会员分享,可在线阅读,更多相关《程序设计.doc(18页珍藏版)》请在冰点文库上搜索。
第四节程序设计方法
前面已讨论指令系统和汇编语言程序设计基础,而设计一个好的程序不仅要能正常运行,完成要求的功能,还应该具有下列特点:
(1)程序结构模块化,程序易读、易调试及维护。
(2)执行速度快。
(3)占用空间小。
尤其是结构化设计,在程序复杂的情况下尤为重要。
一般汇编语言程序设计的基本步骤如下:
(1)分析问题,抽象出描述问题的数学模型,并确定实现数学模型的算法。
(2)绘制程序流程图,通常先画粗框图,在结构模块中再画细框图。
框图一般有:
起始框、执行框、判断框、终止框。
(P170图4-11)
(3)分配存储空间及工作单元。
分配数据段、堆栈段、程序段各在内存什幺位置,各个寄存器主要作什幺用。
(4)按流程图编写程序
(5)静态检查,上机调试
(6)程序运行,结果分析。
在汇编语言程序设计时,通常有四种结构:
顺序结构、分支结构、循环结构、子程序结构。
下面说明。
一、顺序结构:
顺序结构的程序一般是简单程序,程序顺序执行,无分支、无循环、无转移,框图中无判断框。
例1将一字节数据从数据段的某个单元传送到另一个单元
假设源数据在数据段的FIRST单元中,应将此数据传送到数据段的SECOND单元中,流程图如右:
程序如下:
DATASEGMENT
FIRSTDB4CH
SECONTDB?
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
MOVAX,DATA
MOVDS,AX
MOVAL,FIRST
MOVSECONT,AL
CODEENDS
END
(1)从程序可以看出,首先设置两个段,一个段名为DATA的数据段,另一个段名为CODE的代码段(程序段),段定义都用SEGMENT和ENDS伪指令,在代码段的首部用ASSUME伪指令来指定CS和DS的段地址。
(2)程序中第一、二条指令是用来给DS赋给数据段的段地址,因没有立即数直接送DS传送指令,必须通过AX来传送。
(3)第三条指令是把FIRST存储单元存储的数据4CH送到AL寄存器,因为AL寄存器已隐含字节数据类型,存储器操作数也是定义为字节单元,因此存储器操作数可以不用数据类型属性操作符来说明,采用直接寻址方式。
(4)第四条指令是将AL寄存器中的内容送到SECONT存储单元中。
(5)存储单元的偏移地址都采用符号地址,即变量名。
例2将存储器中的二个字节相加,结果(和)送到另一个存储单元中
此题的算法思想,是先将一个字节数据从存储单元送入累加器,然后再把累加器的内容与第二存储单元中的数据相加(如果不产生进位),将结果(和)在从累加器送回存储器存放结果的单元中。
假设被加数和加数存放在ADD_BUF存储单元相邻二个字节单元中,因为不考虑进位,所以和存放在SUM_BUF字节单元中,流程图:
程序如下:
DATASEGMENT
ADD_BUFDB47H,6AH
SUM_BUFDB?
开始
DATAENDS
CODESEGMEMT
AH(ADD-BUF)
ASSUMECS:
CODE,DS:
DATA
MOVAX,DATA
AHAH+(ADD-UF+1)
MOVDS,AX
MOVAH,ADD_BUF
SUMAH
ADDAH,ADD_BUF+1
MOVSUM_BUF,AH
结束
CODEENDS
END
其中数据段ADD_BUF为符号地址的相邻两单元中用DB伪指令定义存放两个将要相加的字节47H和6AH,结果单元SUM_BUF用DB伪指令定义留一个空字节单元。
程序中第三条指令是将一个加数从ADD_BUF单元取入AH中。
第四条指令是将第一个加数(在AH中)和第二个加数相加,第二个加数用符号地址ADD_BUF+1的直接寻址存储器操作数形式取出数据,和在AH中。
第五条指令是将和送入SUM_BUF单元中。
例3将存储单元中的两个数据互换
假设数据段中FIRST单元有一个字节数据和附加段中SECOND单元一字节数据互换存储单元,如下图所示:
数据段数据段
DSDS
FIRST89HFIRSTA7H
附加段附加段
ESES
SECONDA7HSECOND89H
互换前互换后
设计思路是:
先将两个单元的内容分别送入CPU内部寄存器,然后在互换存储单元。
程序如下:
DATASEGMENT
FIRSTDB89H
DATAENDS
EXTRASEGMENT
SECONDDB0A7H
EXTRAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
ASSUMEES:
EXTRA
MOVAX,DATA
MOVDS,AX
MOVAX,EXTRA
MOVES,AX
MOVCL,FIRST
MOVBL,ES:
SECOND
MOVFIRST,BL
MOVES:
SECOND,CL
CODEENDS
END
(1)此时程序中设置了两个存储数据的区段,FIRST存储单元在数据段中,SECOND存储单元在附加段中,因此用ASSUME伪指令分别指明DS和ES的段名。
(2)程序开始的4条指令中,把段地址DATA赋予DS,段地址EXTRA赋予ES。
(3)用4条MOV指令正好做到FIRST单元的内容和SECOND单元的内容互换一下,而借助了CL和BL寄存器。
(4)指令中的存储器操作数一般约定在数据段中,如果存储器操作数要更换在其它段中,必须采用段超越前缀,所以符号地址SECOND单元中的操作数,必须在符号地址前加“ES”。
(5)上述互换操作也可以直接采用指令XCHG(互换指令)来实现,程序如下:
.
MOVBL,FIRST
XCHGBL,ES:
SECOND
MOVFIRST,BL
.
注意不能通过一条XCHG指令,将两个存储单元内容互换,即:
XCHGFIRST,ES:
SECOND
本指令是不存在的,必须要通过一个寄存器,执行三条指令,才能互换。
例4将一压缩BCD码转换为两个ASCII码
(1)将一字节BCD码从存储单元BCD_BUF中取入寄存器;
(2)将两位BCD码一分为二拆开,形成两位非压缩的BCD码
(3)分别加30H,形成两个ASCII码
(4)按先高后低的次序存入ASC_BUF符号地址的连续两个单元
流程图如图:
开始
程序如下:
DATASEGMENT
将压缩的BCD码取入AL
BCD_BUFDB96H
BLAL
ASC_BUFDB2DUP(?
)
DATAENDS
BL内容左移4位
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
ALAL+30H
MOVAX,DATA
MOVDS,AX
高位ASCII码存入存储单元
MOVAL,BCD_BUF
BLBL+30H
MOVBL,AL
MOVCL,4
低位ASCII码存入存储单元
SHRAL,CL
ADDAL,30H
结束
MOVASC_BUF,AL
ANDBL,0FH
ADDBL,30H
MOVASC_BUF+1,BL
CODEENDS
END
例4内存中自TABLE开始的7个单元连续存放着自然数0~6的立方值,任一个数X(0≤X≤6)在FIRST单元中,要求查表找出X的立方值,把结果存入SECOND单元。
因为0--6立方表存放的次序是顺序的,所以表首为0,地址为TABLE,第二个为1,地址为TABLE+1,......,因此X数的地址必然为TABLE+X。
只要计算得到表地址后,从此表中取出立方数,就是X的立方数,在存入SECOND单元,流程图如图。
程序如下:
DATASEGMENT
结束
TABLEDB0,1,8,27,64,125,216
FIRSTDBX
将TABLE的偏移地址送入BX
SECONDDB?
DATAENDS
BXBX+(FIRST)
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
以BX作间接寻址取出立方数存入AL
MOVAX,DATA
MOVDS,AX
(SECOND)AL
MOVBX,OFFSETTABLE
MOVAH,0
结束
MOVAL,FIRST
ADDBX,AX
MOVAL,[BX]
MOVSECOND,AL
CODEENDS
END
第三行指令使TABLE偏移地址送BX;
第四、五行取出X形成(扩展)的十六位数存入AX
第六行形成TABLE+X
第七行指令执行结果,从表地址为TABLE+X的单元中取出的内容,即X的立方数送入AL寄存器,再经下一条指令存入SECOND单元。
二、分支结构:
从8086/8088指令相同可知,它具有许多带条件的转移指令,这就意味着8086/8088组成的计算机具有很强的逻辑判断能力,并且能够根据这种逻辑判断选择执行不同程序段,即可以根据某些条件来进行逻辑判断,当满足条件时可以进行某种处理,当不满足时又可进行另一处理,使计算机在处理事务和数值运算时,更具一定的灵活性,可以说具有某些智能的功能,这就用到分支程序设计。
分支程序结构可以有两种:
双分支和多分支,程序结构框图如下:
P131图4-10
例1比较两个无符号数的大小,把大数存入MAX单元
比较两个无符号数,可采用CF标志位来判断大小,程序框图如下:
开始
程序如下:
ALX1
DATASEGMENT
SOURCEDBX1,X2
X1-X2≥0?
MAXDB?
DATAENDS
CODESEGMENT
ALX2
ASSUMECS:
CODE,DS:
DATA
MOVAX,DATA
(MAX)AL
MOVDS,AX
MOVAL,SOURCE
结束
CMPAL,SOURCE+1
JNCBRANCE
MOVAL,SOURCE+1
BRANCE:
MOVMAX,AL
CODEENDS
END
例2符号函数1当X>0
Y=0当X=0
-1当X<0
假设任意给定的X值存放在XX单元,函数Y的值存放在YY单元,根据X的不同值求Y的算法如图:
程序如下:
DATASEGMENT
XXDBX
YYDB?
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
MOVAX,DATA
MOVDS,AX
MOVAL,XX
CMPAL,0
JGEBIGPR
MOVYY,0FFH
HLT
BIGPR:
JEEQUPR
MOVYY,1
HLT
EQUPR:
MOVYY,0
HLT
CODEENDS
END
例3:
已知两个整数变量A和B,试编写完成下序存在的程序:
(1)若两个数中有一个为奇数,则将奇数存入A_BUF,偶数存入B_BUF。
(2)若两个数均为奇数,则两数分别加1,并存回原变量处。
(3)若两数均为偶数,则两变量不变。
流程图如图:
A、B两变量预先存放在数据段的A_BUF和B_BUF的字节单元中,其值分别为X1、X2。
为了要判断奇数还是偶数,主要决定于一个数的最低位是1还是0,0为偶数,1为奇数,因此可采用位测试的办法来判断:
首先判断A和是否同种类型的数,不是同种类型,再判B是否偶数,由B的类型,就定下A的类型,再按要求
(1)进行处理;同样当是同种类型时,也判B是否偶数,由B的类型就定下A的类型,再按要求
(2)或(3)进行处理。
程序如下:
DATASEGMENT
A_BUFDBX1
B_BUFDBX2
DATAENDS
CODESEGMENT
MAINPROCFAR
ASSUMECS:
CODE:
DATA
START:
PUSHDS;为返回DOS作准备
XORAX,AX
PUSHAX
MOVAX,DATA
MOVDS,AX
MOVAL,A_BUF
MOVBL,B_BUF
XORAL,BL;测试X1和X2同类否
TESTAL,01H;是同类,转CLASS
JZCLASS
TESTBL,01H;否,测试B是偶数否?
JZEXIT
XCHGBL,A_BUF
MOVB_BUF,BL
JMPEXIT;转EXIT
CLASS:
TESTBL,01H;同类,测试BL是偶数否?
JZEXIT;是,满足3,不变,转EXIT
INCA_BUF;不是,按要求2,两数同时加1
INCB_BUF
EXIT:
RET;返回DOS
MAINENDP
CODEENDS
ENDSTART
三、循环结构:
循环结构是控制CPU重复执行一公共程序段若干次,直到满足某个条件,才结束循环。
基本形式:
三部分组成:
循环参数置初值、循环工作部分、循环控制部分,结构框图如下:
(两种)
P137图4-17
(a)所示的循环结构执行时,循环体至少要执行一次,才判别循环是否结束--先执行后判断--直到型循环。
(b)所示的循环结构执行时,由于先进入循环的控制部分,即先判循环条件是否满足,所以有可能循环一次也不执执行--先判断,后执行--当型循环。
例1:
编程计算SUM=a1+a2+...+a10,已知a1~a10依次存放在以BUFFER为首地址的数据区内,每个数据占两个字节,和SUM也是为两个字节。
我们把相同的指令只书写一次,作为一个公共执行的程序段,控制复执行10次,来完成指定的工作。
为了做到这一点,必须解决两个问题:
(1)必须要设置控制计算机重复执行某段程序的指令
(2)必须要对循环参数进行修改,以便使相同的公共程序段能完成对不同参数的存在处理。
开始
下面画出下面框图,并根据框图编写程序:
BX操作数地址
NAMEEXAP1
DATASEGMENT
CX循环次数
BUFFERDWa1,a2,a3,......,a9,a10
SUMDW?
AXAX+[BX]
DATAENDS
修改操作数地址
BXBX+2
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
CXCX-1=0?
MOVDS,AX
MOVAX,0
SUM和
MOVBX,OFFSETBUFFER
MOVCX,10
结束
LOP:
ADDAX,[BX]
INCBX
INCBX
DECCX
JNZLOP
MOVSUM,AX
CODEENDS
ENDSTART
例2:
编一程序在以BUF为首地址的字节单元中存放了COUNT个无符号数,找出其中最大数送MAX单元。
分析:
这是一个常见的找大数问题,具体算法是:
先出第一个数送入寄存器AL中,将AL中的数依次与后面的COUNT-1个逐个进行比较,如果AL中的数较小,则将较大数送AL寄存器;如果AL中的数较大,则AL保持不变。
在比较过程中,始终保持AL中存放较大数,比较COUNT-1次后,AL中即为最大数,最后将AL中最大数送MAX单元。
开始
这是一个循环次数已知的循环,因此可用寄存器CX作循环计数器,用以控制循环。
BXBUF的地址偏移量
CX比较次数
AL第一个数据
程序流程图见下图:
程序如下:
修改取数地址
BXBX+1
NAMEEXAP2
DATASEGMENT
两数比较:
AL-[BX]
BUFDB1,2,3,100,23,78,90,134
COUNTEQU$-BUF
AL≥[BX]?
MAXDB?
Y
DATAENDS
CODESEGMENTN
AL较大数
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
CXCX—1
MOVDS,AX
MOVBX,OFFSETBUF
CX=0?
MOVCX,COUNT-1;比较次数送CXN
MOVAL,[BX];取第一个数送AL
LOOP1:
INCBXY
MAX大数
CMPAL,[BX];AL与下一个数比较
结束
JAENEXT;若AL>=下一个数则转NEXT
MOVAL,[BX];否则,较大数送AL
NEXT:
DECCX;CX-1送CX,CX不等于0时继续循环
JNZLOOP1;CX=0时,结束循环
MOVMAX,AL;最大数送MAX
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
在循环次数已知的情况下,采用循环控制指令LOOP来替换DECCX,JNZLOOP1,这对循环
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程序设计
![提示](https://static.bingdoc.com/images/bang_tan.gif)