实验7循环程序设计实验.docx
《实验7循环程序设计实验.docx》由会员分享,可在线阅读,更多相关《实验7循环程序设计实验.docx(18页珍藏版)》请在冰豆网上搜索。
实验7循环程序设计实验
实验6中1、2题参考程序
1.设数据区有双精度数据A、B定义例如:
ADD2A3D0B2CH
BDD2573ADEH
求自编程序,计算A与B的和与差,并用十六进制和二进制形式分别显示。
用16进制形式显示程序:
DATASEGMENT
BUFDB5DUP(0)
ADD2A3D0B2CH;存放情况与ADW0B2CH,2A3DH相同
BDD2573ADEH;存放情况与BDW3ADEH,257H相同
CDD0,0
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
;以下参考本实验参考程序段15,注意设定数据类型,加添变量C
MOVAX,WORDPTRA
ADDAX,WORDPTRB
MOVWORDPTRC,AX
MOVAX,WORDPTRA+2
ADCAX,WORDPTRB+2
MOVWORDPTRC+2,AX
;以下调用实验5的参考程序段2,注意将显示内容C的高16位放到AX中。
;同时注意在数据区有变量BUF与A,且A在BUF后面。
MOVAX,WORDPTRC+2
MOVDI,OFFSETA;将DI指向BUF的下一单元
MOVCX,0
MOVBX,16;准备除以16
CBUF10:
DECDI;准备存放余数,往前倒存
INCCX
MOVDX,0;将除数的高16位(在DX中)清0,DX也将用来存放余数
DIVBX;DX,AX除以BX(BX=16)
ADDDL,30H;余数变为ASCII码值
MOVBYTEPTR[DI],DL;存储十六进制数
CMPAX,0;是否为0?
JNZCBUF10;不为0转CBUF10
CHANGE11:
MOVDL,BYTEPTR[DI];取出存放在BUF中的十六进制数到DL供显示
CMPDL,3AH;是否小于10?
JBCHANGE12;如果小于10转显示
ADDDL,7;否则为A到F之间数,加7
CHANGE12:
MOVAH,2;显示1个字符
INT21H
INCDI
LOOPCHANGE11
;以下再调用实验5的参考程序段2,以显示C的低16位。
;注意将显示内容C的低16位放到AX中。
;还要注意改变标号CBUF10到CBUF12为CBUF13到CBUF15
MOVAX,WORDPTRC
MOVDI,OFFSETA;将DI指向BUF的下一单元
MOVCX,0
MOVBX,16;准备除以16
CBUF13:
DECDI;准备存放余数,往前倒存
INCCX
MOVDX,0;将除数的高16位(在DX中)清0,DX也将用来存放余数
DIVBX;DX,AX除以BX(BX=16)
ADDDL,30H;余数变为ASCII码值
MOVBYTEPTR[DI],DL;存储十六进制数
CMPAX,0;是否为0?
JNZCBUF13;不为0转CBUF13
CHANGE14:
MOVDL,BYTEPTR[DI];取出存放在BUF中的十六进制数到DL供显示
CMPDL,3AH;是否小于10?
JBCHANGE15;如果小于10转显示
ADDDL,7;否则为A到F之间数,加7
CHANGE15:
MOVAH,2;显示1个字符
INT21H
INCDI
LOOPCHANGE14
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
本解存在问题:
当低16位字数不到4位时显示结果位数错误。
如果利用子程序完成本题,程序如下:
DATASEGMENT
BUFDB5DUP(0)
ADD2A3D0B2CH;存放情况与AWORDOB2CH,2A3DH相同
BDD2573ADEH;存放情况与AWORD3ADEH,257H相同
CDD0,0
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
;以下参考本实验参考程序段15,注意设定数据类型,加添变量C
MOVAX,WORDPTRA
ADDAX,WORDPTRB
MOVWORDPTRC,AX
MOVAX,WORDPTRA+2
ADCAX,WORDPTRB+2
MOVWORDPTRC+2,AX
;以下调用显示子程序,注意将显示内容C的高16位放到AX中。
MOVAX,WORDPTRC+2
CALLDISP_16
;以下再调用显示子程序,以显示C的低16位。
;注意将显示内容C的低16位放到AX中。
MOVAX,WORDPTRC
CALLDISP_16
;
MOVAH,4CH
INT21H
;以下将实验5的参考程序段2改为子程序。
开始定义子程序名,注意结尾用RET返回。
;注意子程序的位置在MOVAH,4CH与INT21H二句的后面。
;仍然要注意在数据区有变量BUF与A,且A在BUF后面。
DISP_16PROC
MOVDI,OFFSETA;将DI指向BUF的下一单元
MOVCX,0
MOVBX,16;准备除以16
CBUF10:
DECDI;准备存放余数,往前倒存
INCCX
MOVDX,0;将除数的高16位(在DX中)清0,DX也将用来存放余数
DIVBX;DX,AX除以BX(BX=16)
ADDDL,30H;余数变为ASCII码值
MOVBYTEPTR[DI],DL;存储十六进制数
CMPCX,4;是否4个16进制数字?
注意本处略微改动解决了上一解法的问题。
JNZCBUF10;不为0转CBUF10
CHANGE11:
MOVDL,BYTEPTR[DI];取出存放在BUF中的十六进制数到DL供显示
CMPDL,3AH;是否小于10?
JBCHANGE12;如果小于10转显示
ADDDL,7;否则为A到F之间数,加7
CHANGE12:
MOVAH,2;显示1个字符
INT21H
INCDI
LOOPCHANGE11
RET
DISP_16ENDP
CODEENDS
ENDSTART
注:
(1)注意本解中将CMPAX,0这一句改为CMPCX,4就解决了上一解法的问题,即使低16位只有0个、1个、2个、3个非零16进制数字,结果都是正确的。
(2)请在本解基础上考虑如果改为10进制显示,只需要改那二个数字?
如果改为2进制显示,又只需要改那三个数字?
用2进制形式显示程序又一解:
DATASEGMENT
BUFDB5DUP(0)
ADW0B2CH,2A3DH;存放情况与ADW0B2CH,2A3DH相同
BDW3ADEH,257H;存放情况与BDW3ADEH,257H相同
CDW0,0
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
;以下参考本实验参考程序段15,注意设定数据类型,加添变量C
MOVAX,WORDPTRA
ADDAX,WORDPTRB
MOVWORDPTRC,AX
MOVAX,WORDPTRA+2
ADCAX,WORDPTRB+2
MOVWORDPTRC+2,AX
;以下调用显示子程序,注意将显示内容C分4次放到BL中。
MOVBL,BYTEPTRC+3;请想一下以下C的4个字节显示次序为什么如此
CALLDISP_2
MOVBL,BYTEPTRC+2
CALLDISP_2
MOVBL,BYTEPTRC+1
CALLDISP_2
MOVBL,BYTEPTRC
CALLDISP_2
MOVAH,4CH
INT21H
;以下将实验6的参考程序段2改为子程序。
开始定义子程序名,注意结尾用RET返回。
;注意子程序的位置在MOVAH,4CH与INT21H二句的后面。
;要注意显示内容要求放到BL中,每次显示8位。
DISP_2PROC
MOVCL,8
NEXT:
MOVDL,0
SALBL,1
RCLDL,1
ADDDL,30H
MOVAH,2
INT21H
DECCL
JNENEXT
RET
DISP_2ENDP
CODEENDS
ENDSTART
减法程序与以上程序类似,不再给出解答。
2.设数据区有双精度数据A=2A3D0B2CH、B=2573ADEH,其存储情况如下所示。
求自编程序,计算A与B的积,放到数据区的X1,X2,X3,X4四个字单元中,再求用十六进制形式显示。
A1DW2A3DH
A2DW0B2CH
B1DW532DH
B2DW3ADEH
X1DW0
X2DW0
X3DW0
X4DW0
提示:
如上数据区有字变量X1,X2,X3,X4;初值均为0;X1准备存结果的最高16位;X4准备存结果的最低16位;将A看成A1,A2;A1为高16位,A2为低16位;同样,B看成B1,B2。
那么,可以将B2与A2的积加到X3,X4中;将B2与A1的积加到X2,X3中;将B1与A2的积加到X2,X3中;将B1与A1的积加到X1,X2中;注意进位。
DATASEGMENT
BUFDB5DUP(0)
ADB0;BUF之后标志,满足显示子程序的要求
A1DW2A3DH
A2DW0B2CH
B1DW532DH
B2DW3ADEH
X1DW0
X2DW0
X3DW0
X4DW0
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
;以下参考本实验参考程序段1
MOVAX,A1
MULB1
MOVX1,AX
MOVX2,DX
;以下再参考本实验参考程序段1,注意乘数与乘积位置,
;再注意以加的方式加到存储单元中
MOVAX,A1
MULB2
ADDX2,AX
ADCX3,DX
MOVAX,A2
MULB1
ADDX2,AX
ADCX3,DX
MOVAX,A2
MULB2
ADDX3,AX
ADCX4,DX
;以下调用显示子程序。
MOVAX,X4
CALLDISP_16
MOVAX,X3
CALLDISP_16
MOVAX,X2
CALLDISP_16
MOVAX,X1
CALLDISP_16
MOVAH,4CH
INT21H
;以下为实验5的参考程序段2改的子程序。
;仍然要注意在数据区有变量BUF与A,且A在BUF后面。
DISP_16PROC
MOVDI,OFFSETA;将DI指向BUF的下一单元
MOVCX,0
MOVBX,16;准备除以16
CBUF10:
DECDI;准备存放余数,往前倒存
INCCX
MOVDX,0;将除数的高16位(在DX中)清0,DX也将用来存放余数
DIVBX;DX,AX除以BX(BX=16)
ADDDL,30H;余数变为ASCII码值
MOVBYTEPTR[DI],DL;存储十六进制数
CMPCX,4;是否到4个字?
JNZCBUF10;不为0转CBUF10
CHANGE11:
MOVDL,BYTEPTR[DI];取出存放在BUF中的十六进制数到DL供显示
CMPDL,3AH;是否小于10?
JBCHANGE12;如果小于10转显示
ADDDL,7;否则为A到F之间数,加7
CHANGE12:
MOVAH,2;显示1个字符
INT21H
INCDI
LOOPCHANGE11
RET
DISP_16ENDP
CODEENDS
ENDSTART
实验7循环程序认识与设计练习
一、实验内容:
自编算术运算、逻辑运算、移位运算程序段,和供参考的数据转换、显示程序段组合成完整程序,上机实现并验证。
二、实验目的:
1.通过参考程序段的1与2,了解循环程序的结构与意义。
2.复习双精度数运算程序设计方法。
3.复习逻辑运算、移位运算指令内容与使用方法,学习用这些指令解决实际问题的方法。
4.熟悉常见的算术运算、逻辑运算、移位运算程序设计方法。
5.学习1号、2号、9号DOS系统功能调用的使用方法
6.复习数据转换程序与显示程序设计方法
7.学习将多个程序段拼凑设计程序的方法
三、实验题目
1.求利用2号中断接受从键盘输入的最多4个16进制数字组成一个16进制数,并依次用十六进制、十进制显示的程序。
2.接上题,求将字变量BUF的值乘以上述16进制数,再用十六进制数显示的程序。
3.在内存的源数据区SOURCE处有若干个ASCII码字符,要求将其中的英文大写字母转换为小写字母,其它字符不转换,并存放到结果数据区DEST处。
已知数据区如下。
DATASEGMENT
SOURCEDB‘BEIjin2008OLYMPIC’
COUNTEQU$-SOURCE;字符个数
DESTDBCOUNTDUP(?
)
DATAENDS
分析:
英文大写字母‘A’—‘Z’,ASCII码值为41H—5AH。
相应的小写字母为‘a’—‘z’,ASCII码值为61H—7AH。
英文大写字母要转换为相应的小写字母只要ASCII码值加20H即可。
4.修改上述程序:
将输入到数据区DEST处的字符串在屏幕上显示出来。
5.将以下参考程序段中第3到9题补充完整再上机验证。
供参考的程序段:
(1)二进制数转换为十六进制数显示。
要求在数据区设置BUFDB10DUP(0)和D0,例如D0DW1234H
MOVDI,OFFSETBUF+10;到存储区尾部
DECDI;到上一单元
MOV[DI],BYTEPTR'$';9号功能调用要显示内容最后加'$'表示字串结束
MOVAX,D0;取要用来变十进制数的数到AX
MOVBX,16;准备除以16
CHANGE10:
DECDI;到上一单元
MOVDX,0;将除数的高16位(在DX中)清0,DX也将用来存放余数
DIVBX;DX,AX除以BX(BX=10)
ADDDL,30H;余数变为ASCII码值
MOVBYTEPTR[DI],DL;存储十六进制数
CMPAX,0;是否为0?
JNZCHANGE10;不为0转CHANGE10
CHANGE11:
MOVDX,DI;取出存放在BUF中的ASCII码形式的十六进制数首地址到DX中供显示
MOVAH,9;显示十六进制数
INT21H
(2)ASCII码表示的十进制数转换为二进制数并显示。
要求在数据区设置要求显示的BUF数据,DB类型
MOVSI,OFFSETBUF;将BUF的地址放到SI中
MOVDX,0;清DX为0;
MOVCX,5;置循环次数为5
MOVBX,10
GET_ASC:
MOVAL,[SI];取出一个字符
CMPAL,'0';必须保证5个数都是十进制数(0-9)
JBEXIT
CMPAL,'9'
JAEXIT;判断是否是“0”-“9”
DEC_BIN:
SUBAL,30H;减30H变二进制数
MOVAH,0
PUSHAX;转换为对应的数并置于AX中,转存堆栈
MOVAX,DX
MULBX;AX内容乘10
MOVDX,AX
POPAX
ADDDX,AX;(DX)←(DX)*10+(AX)
INCSI;使指针SI指向下一个字符
DECCX
JNZGET_ASC
MOVBX,DX;取要显示的字符到BL中
MOVCL,16;移16次,最大数64000
NEXT:
MOVDX,0
SALBX,1
RCLDX,1
ADDDX,30H
MOVAH,2
INT21H
DECCL
JNENEXT
(3)以移位方式显示16进制数(要求在数据区设置用来变十六进制数的数D0,例如D0DW1234h)
解1:
MOVSI,D0;取要用来变十六进制数的数到SI
MOVBX,4;每个字显示4个16进制字符
CHANGE10:
MOVCX,4;准备左移4位(除以16)
MOVDX,0;将显示内容存储器(在DX中)清0
CHANGE20:
SHLSI,1;SI移一位到进位位
RCLDX,1;进位位移到DX
LOOPCHANGE20;移4次
ADDDL,30H;一个16进制数变为ASCII码值
CMPDL,3AH;是否小于10?
JBCHANGE12;如果小于10转显示
ADDDL,7;否则为A到F之间数,加7
CHANGE12:
MOVAH,2;显示1个字符
INT21H
DECBX;处理下一个字符
CMPBX,0;是否为0?
JNZCHANGE10;不为0转CHANGE10
解2:
MOVSI,D0;取要用来变十六进制数的数到SI
MOVBX,4;每个字显示4个16进制字符
CHANGE10:
MOVCL,4;准备循环左移4位
ROLSI,CL;SI循环左移4位
MOVDX,SI;SI内容送显示
ANDDL,0FH
ADDDL,30H;一个16进制数变为ASCII码值
CMPDL,3AH;是否小于10?
JBCHANGE12;如果小于10转显示
ADDDL,7;否则为A到F之间数,加7
CHANGE12:
MOVAH,2;显示1个字符
INT21H
DECBX;处理下一个字符
CMPBX,0;是否为0?
JNZCHANGE10;不为0转CHANGE10
(4)ASCII码表示的十六进制数到二进制数的转换
INPUT:
MOVAH,01H
INT21H;键盘输入
SUBAL,30H
JLEXIT;输入其它字符
CMPAL,0AH
JLCHANGE;输入0-9
SUBAL,07H
CMPAL,0AH
JLEXIT;输入其它字符
CMPAL,0FH
JLECHANGE;输入A-F
SUBAL,20H
CMPAL,0AH
JLEXIT;输入其它字符
CMPAL,0FH
JLECHANGE;输入a-f
JMPEXIT;输入其它字符
CHANGE:
MOVCL,4
SHLDX,CL
MOVAH,0
ADDDX,AX;(DX)←(DX)*16+(AX)
DECBL
JNZINPUT
EXIT:
MOVBX,DX;取要显示的字符到BL中
MOVCL,16;移16次
NEXT:
MOVDX,0
SALBX,1
RCLDX,1
ADDDX,30H
MOVAH,2
INT21H
DECCL
JNENEXT
(5)十进制数的ASCII码转换为压缩型BCD码。
要求在数据区有ASC_BUF、BCDBUF二个数据集,由若干个十进制数的ASCII码字符组成,要定义其长度放到COUNT中。
MOVSI,OFFSETASC_BUF
MOVDI,OFFSETBCDBUF
MOVCX,COUNT
MOVBX,CX
SHRBX,1;BX右移一位,等效于除2
JNCEVEN1;(CF)=0,则CX为偶数
MOVBL,[SI];对首位单独进行处理
ANDBL,0FH
MOV[DI],BL
DECCX
INCSI
INCDI
EVEN1:
MOVAL,[SI]
ANDAL,0FH;清高4位为0
MOVBL,[SI+1]
ANDBL,0FH;清高4位为0
MOVDL,16
MULDL
ADDAL,BL
MOV[DI],AL
ADDSI,2
INCDI
DECCX
JNZEVEN1
(6)BCD码转换为十进制数的ASCII码,要求在数据区有ASC_BUF数据,DB类型,共3个数据。
MOVSI,OFFSETBCD_BUF
ADDSI,3
MOVCX,3
MOVDH,0
CHG_OUT1:
PUSHCX
MOVAL,[SI];取压缩BCD码
DECSI;修改指针
MOVDL,AL
MOVCL,4
RORAL,CL
ANDAL,0FH;取高半字节BCD码
ADDAL,30H;生成ASCII码
MOVDL,AL
MOVAH,2
INT21H;标准设备输出
MOVAL,DL
ANDAL,0FH;取低半字节BCD码
ADDAL,30H;生成ASCII码
MOVDL,AL
MOVAH,2
INT21H;标准设备输出
POPCX
DECCX
JNZCHG_OUT1
(7)双字除10取余求变10进制数(设双字在DXAX中,除数10在BX中,在数据区中准备字节类型10个字数据区D:
DDB10DUP(?
))
LEADI,D+10
MOV[DI],BYTEPTR'$';准备调用9号中断显示程序
DECDI;到上一单元
MOVSI,AX;保存AX
MOVAX,DX;取要用来变十进制数的数的高16位到AX
MOVBX,10;准备除以10
CHANGE10:
MOVDX,0;将除数的高16位(在DX中)清0,DX也将用来存放余数
DIVBX;DX,AX除以BX(BX=10)
MOVCX,AX;保存高16位除以10的商
MOVAX,SI;再恢复AX中原来的双字的低16位
DIVBX
ADDDL,30H;余数变为ASCII码值
MOVBYTEPTR[DI],DL;存储十进制数
DECDI;到上一单元
MOVSI,AX