IBMPC汇编语言程序设计课后习题答案第二版沈美明.docx
《IBMPC汇编语言程序设计课后习题答案第二版沈美明.docx》由会员分享,可在线阅读,更多相关《IBMPC汇编语言程序设计课后习题答案第二版沈美明.docx(37页珍藏版)》请在冰豆网上搜索。
IBMPC汇编语言程序设计课后习题答案第二版沈美明
第五章
5.1试编写一个汇编语言程序,要求对键盘输入的小写字母用大写字母显示出
来。
答:
程序段如下:
BEGIN:
MOVAH,1;从键盘输入一个字符的DOS调用
INT21H
CMPAL,‘a’;输入字符<‘a’吗?
JBSTOP
CMPAL,‘z’;输入字符>‘z’吗?
JASTOP
SUBAL,20H;转换为大写字母,用ANDAL,11011111B也可
MOVDL,AL;显示一个字符的DOS调用
MOVAH,2
INT21H
JMPBEGIN
STOP:
RET
5.2编写程序,从键盘接收一个小写字母,然后找出它的前导字符和后续字符,
再按顺序显示这三个字符。
答:
程序段如下:
BEGIN:
MOVAH,1;从键盘输入一个字符的DOS调用
INT21H
CMPAL,‘a’;输入字符<‘a’吗?
JBSTOP
CMPAL,‘z’;输入字符>‘z’吗?
JASTOP
DECAL;得到前导字符
MOVDL,AL;准备显示三个字符
MOVCX,3
DISPLAY:
MOVAH,2;显示一个字符的DOS调用
INT21H
INCDL
LOOPDISPLAY
STOP:
RET
5.3将AX寄存器中的16位数分成4组,每组4位,然后把这四组数分别放在
5.4AL、BL、CL和DL中。
答:
程序段如下:
DSEGSEGMENT
STOREDB4DUP(?
)
DSEGENDS
┇
BEGIN:
MOVCL,4;右移四次
MOVCH,4;循环四次
LEABX,STORE
A10:
MOVDX,AX
ANDDX,0FH;取AX的低四位
MOV[BX],DL;低四位存入STORE中
INCBX
SHRAX,CL;右移四次
DECCH
JNZA10;循环四次完了码?
B10:
MOVDL,STORE;四组数分别放在AL、BL、CL和DL中
MOVCL,STORE+1
MOVBL,STORE+2
MOVAL,STORE+3
STOP:
RET
5.5试编写一程序,要求比较两个字符串STRING1和STRING2所含字符是否完全
相同,若相同则显示‘MATC’H,若不相同则显示‘NOMATC’H。
答:
程序如下:
DSEGSEGMENT
STRING1DB‘Iamastudent.’
STRING2DB‘Iamastudent!
’
YESDB‘MATC’H,0DH,0AH,‘$’
NODB‘NOMATC’H,0DH,0AH,‘$’
DSEGENDS
;
---------------------------------------------------------------------
-----
CSEGSEGMENT
MAINPROCFAR
ASSUMECS:
CSEG,DS:
DSEG,ES:
DSEG
START:
PUSHDS;设置返回DOS
SUBAX,AX
PUSHAX
MOVAX,DSEG
MOVDS,AX;给DS赋值
MOVES,AX;给ES赋值
;
BEGIN:
LEASI,STRING1;设置串比较指令的初值
LEADI,STRING2
CLD
MOVCX,STRING2-STRING1
REPECMPSB;串比较
JNEDISPNO
LEADX,YES;显示MATCH
JMPDISPLAY
DISPNO:
LEADX,NO;显示NOMATCH
DISPLAY:
MOVAH,9;显示一个字符串的DOS调用
INT21H
RET
MAINENDP
CSEGENDS;以上定义代码段
;
---------------------------------------------------------------------
-----
ENDSTART
5.6试编写一程序,要求能从键盘接收一个个位数N,然后响铃N次(响铃的ASCII
5.7码为07)。
答:
程序段如下:
BEGIN:
MOVAH,1;从键盘输入一个字符的DOS调用
INT21H
SUBAL,‘0’
JBSTOP;输入字符<‘0’吗?
CMPAL,9;输入字符>‘9’吗?
JASTOP
CBW
MOVCX,AX;响铃次数N
JCXZSTOP
BELL:
MOVDL,07H;准备响铃
MOVAH,2;显示一个字符的DOS调用,实际为响铃
INT21H
CALLDELAY100ms;延时100ms
LOOPBELL
STOP:
RET
5.8编写程序,将一个包含有20个数据的数组M分成两个数组:
正数数组P和
负数数组N,并分别把这两个数组中数据的个数显示出来。
答:
程序如下:
DSEGSEGMENT
COUNTEQU20
ARRAYDW20DUP(?
);存放数组
COUNT1DB0;存放正数的个数
ARRAY1DW20DUP(?
);存放正数
COUNT2DB0;存放负数的个数
ARRAY2DW20DUP(?
);存放负数
ZHENDB0DH,0AH,‘Thepositivenumberis:
’,‘$’;正数的个数是:
FUDB0DH,0AH,‘Thenegativenumberis:
’,‘$’;负数的个数是:
CRLFDB0DH,0AH,‘$’
DSEGENDS
;
---------------------------------------------------------------------
-----
CSEGSEGMENT
MAINPROCFAR
ASSUMECS:
CSEG,DS:
DSEG
START:
PUSHDS;设置返回DOS
SUBAX,AX
PUSHAX
MOVAX,DSEG
MOVDS,AX;给DS赋值
BEGIN:
MOVCX,COUNT
LEABX,ARRAY
LEASI,ARRAY1
LEADI,ARRAY2
BEGIN1:
MOVAX,[BX]
CMPAX,0;是负数码?
JSFUSHU
MOV[SI],AX;是正数,存入正数数组
INCCOUNT1;正数个数+1
ADDSI,2
JMPSHORTNEXT
FUSHU:
MOV[DI],AX;是负数,存入负数数组
INCCOUNT2;负数个数+1
ADDDI,2
NEXT:
ADDBX,2
LOOPBEGIN1
LEADX,ZHEN;显示正数个数
MOVAL,COUNT1
CALLDISPLAY;调显示子程序
LEADX,FU;显示负数个数
MOVAL,COUNT2
CALLDISPLAY;调显示子程序
RET
MAINENDP
;
---------------------------------------------------------------------
-----
DISPLAYPROCNEA;R显示子程序
MOVAH,9;显示一个字符串的DOS调用
INT21H
AAM;将(AL)中的二进制数转换为二个非压缩BCD码
ADDAH,‘0’;变为0~9的ASCII码
MOVDL,AH
MOVAH,2;显示一个字符的DOS调用
INT21H
ADDAL,‘0’;变为0~9的ASCII码
MOVDL,AL
MOVAH,2;显示一个字符的DOS调用
INT21H
LEADX,CRLF;显示回车换行
MOVAH,9;显示一个字符串的DOS调用
INT21H
RET
DISPLAYENDP;显示子程序结束
CSEGENDS;以上定义代码段
;
---------------------------------------------------------------------
-----
ENDSTART
5.9试编写一个汇编语言程序,求出首地址为DATA的100D字数组中的最小偶数,
并把它存放在AX中。
答:
程序段如下:
BEGIN:
MOVBX,0
MOVCX,100
COMPARE:
MOVAX,DATA[BX;]取数组的第一个偶数
ADDBX,2
TESTAX,01H;是偶数吗?
LOOPNZCOMPA;RE不是,比较下一个数
JNZSTOP;没有偶数,退出
JCXZSTOP;最后一个数是偶数,即为最小偶数,退出
COMPARE1:
MOVDX,DATA[BX;]取数组的下一个偶数
ADDBX,2
TESTDX,01H;是偶数吗?
JNZNEXT;不是,比较下一个数
CMPAX,DX;(AX)<(DX)吗?
JLENEXT
MOVAX,DX;(AX)<(DX),则置换(AX)为最小偶数
NEXT:
LOOPCOMPARE1
STOP:
RET
5.10把AX中存放的16位二进制数K看作是8个二进制的“四分之一字节”。
试
编写程序要求数一下值为3(即11B)的四分之一字节数,并将该数(即11B的个数)
在终端上显示出来。
答:
程序段如下:
BEGIN:
MOVDL,0;计数初始值
MOVCX,8
COMPARE:
TESTAX,03H;是数03吗?
JNZNOEQUAL;不是,转走
INCDL;是,计数
NOEQUAL:
RORAX,1;准备判断下一个数
RORAX,1
LOOPCOMPARE
ADDDL,‘0’;将计数值转换为ASCII码
MOVAH,2;进行显示
INT21H
STOP:
RET
5.11试编写一个汇编语言程序,要求从键盘接收一个四位的16进制数,并在终
端上显示与它等值的二进制数。
答:
程序段如下:
BEGIN:
MOVBX,0;用于存放四位的16进制数
MOVCH,4
MOVCL,4
INPUT:
SHLBX,CL;将前面输入的数左移4位
MOVAH,1;从键盘取数
INT21H
CMPAL,30H;<0吗?
JBINPUT;不是‘0~F’的数重新输入
CMPAL,39H;是‘0~9’吗?
JAAF;不是,转‘A~F’的处理
ANDAL,0FH;转换为:
0000B~1001B
JMPBINARY
AF:
ANDAL,11011111B;转换为大写字母
CMPAL,41H;又JBINPUT;不是‘A~F’的数重新输入
CMPAL,46H;>F吗?
JAINPUT;不是‘A~F’的数重新输入
ANDAL,0FH;转换为:
1010B~1111B
ADDAL,9
BINARY:
ORBL,AL;将键盘输入的数进行组合
DELCH
JNZINPUT
DISPN:
MOVCX,16;将16位二进制数一位位地转换成ASCII码显示
DISP:
MOVDL,0
ROLBX,1
RCLDL,1
ORDL,30H
MOVAH,2;进行显示
INT21H
LOOPDISP
STOP:
RET
5.12设有一段英文,其字符变量名为ENG,并以$字符结束。
试编写一程序,查
5.13对单词SUN在该文中的出现次数,并以格式“SUN:
xxxx”显示出次数。
答:
程序如下:
DSEGSEGMENT
ENGDB‘Hereissun,sun,,,$’
DISPDB‘SUN:
’
DATDB‘0000’,0DH,0AH,‘$’
KEYWORDD‘Bsun’
DSEGENDS
;
---------------------------------------------------------------------
-----
CSEGSEGMENT
MAINPROCFAR
ASSUMECS:
CSEG,DS:
DSEG,ES:
DSEG
START:
PUSHDS;设置返回DOS
SUBAX,AX
PUSHAX
MOVAX,DSEG
MOVDS,AX;给DS赋值
MOVES,AX;给ES赋值
BEGIN:
MOVAX,0
MOVDX,DISP-ENG-2;计算ENG的长度(每次比较sun,因此比较次数-2)
LEABX,ENG
COMP:
MOVDI,BX
LEASI,KEYWORD
MOVCX,3
REPECMPSB;串比较
JNZNOMATCH
INCAX;是,SUN的个数加1
ADDBX,2
NOMATCH:
INCBX;指向ENG的下一个字母
DECDX
JNZCOMP
DONE:
MOVCH,4;将次数转换为16进制数的ASCII码
MOVCL,4
LEABX,DAT;转换结果存入DAT单元中
DONE1:
ROLAX,CL
MOVDX,AX
ANDDL,0FH;取一位16进制数
ADDDL,30H
CMPDL,39H
JLESTORE
ADDDL,07H;是“A~F”所以要加7
STORE:
MOV[BX],DL;转换结果存入DAT单元中
INCBX
DECCH
JNZDONE1
DISPLAY:
LEADX,DISP;显示字符串程序(将DISP和DAT一起显示)
MOVAH,09H
INT21H
RET
MAINENDP
CSEGENDS;以上定义代码段
;
---------------------------------------------------------------------
-----
ENDSTART
5.14从键盘输入一系列以$为结束符的字符串,然后对其中的非数字字符计数,
并显示出计数结果。
答:
程序段如下:
DSEGSEGMENT
BUFFDB50DUP(‘’)
COUNTDW0
DSEGENDS
┇
BEGIN:
LEABX,BUFF
MOVCOUNT,0
INPUT:
MOVAH,01;从键盘输入一个字符的功能调用
INT21H
MOV[BX],AL
INCBX
CMPAL,‘$’;是$结束符吗?
JNZINPUT;不是,继续输入
LEABX,BUFF;对非数字字符进行计数
NEXT:
MOVCL,[BX]
INCBX
CMPCL,‘$’;是$结束符,则转去显示
JZDISP
CMPCL,30H;小于0是非数字字符
JBNEXT
CMPCL,39H;大于9是非数字字符
JANEXT
INCCOUNT;个数+1
JMPNEXT
DISP:
┇;16进制数显示程序段(省略)
5.15有一个首地址为MEM的100D字数组,试编制程序删除数组中所有为0的项,
5.16并将后续项向前压缩,最后将数组的剩余部分补上0。
答:
程序如下:
DSEGSEGMENT
MEMDW100DUP(?
)
DSEGENDS
;
---------------------------------------------------------------------
-----
CSEGSEGMENT
MAINPROCFAR
ASSUMECS:
CSEG,DS:
DSEG
START:
PUSHDS;设置返回DOS
SUBAX,AX
PUSHAX
MOVAX,DSEG
MOVDS,AX;给DS赋值
BEGIN:
MOVSI,(100-1)*2;(SI)指向MEM的末元素的首地址
MOVBX,-2;地址指针的初值
MOVCX,100
COMP:
ADDBX,2
CMPMEM[BX],0
JZCONS
LOOPCOMP
JMPFINISH;比较完了,已无0则结束
CONS:
MOVDI,BX
CONS1:
CMPDI,SI;到了最后单元码?
JAENOMOV
MOVAX,MEM[DI+2];后面的元素向前移位
MOVMEM[DI],AX
ADDDI,2
JMPCONS1
NOMOV:
MOVWORDPTR[SI],0;最后单元补0
LOOPCOMP
FINISH:
RET
MAINENDP
CSEGENDS;以上定义代码段
;
---------------------------------------------------------------------
-----
ENDSTART
5.17在STRING到STRING+99单元中存放着一个字符串,试编制一个程序测试该
字符串中是否存在数字,如有则把CL的第5位置1,否则将该位置0。
答:
程序如下:
DSEGSEGMENT
STRINGDB100DUP(?
)
DSEGENDS
;
---------------------------------------------------------------------
-----
CSEGSEGMENT
MAINPROCFAR
ASSUMECS:
CSEG,DS:
DSEG
START:
PUSHDS;设置返回DOS
SUBAX,AX
PUSHAX
MOVAX,DSEG
MOVDS,AX;给DS赋值
BEGIN:
MOVSI,0;(SI)作为地址指针的变化值
MOVCX,100
REPEAT:
MOVAL,STRING[SI]
CMPAL,30H
JBGO_ON
CMPAL,39H
JAGO_ON
ORCL,20H;存在数字把CL的第5位置1
JMPEXIT
GO_ON:
INCSI
LOOPREPEAT
ANDCL,0DFH;不存在数字把CL的第5位置0
EXIT:
RET
MAINENDP
CSEGENDS;以上定义代码段
;
---------------------------------------------------------------------
-----
ENDSTART
5.18在首地址为TABLE的数组中按递增次序存放着100H个16位补码数,试编
写一个程序把出现次数最多的数及其出现次数分别存放于AX和CX中。
答:
程序如下:
DSEGSEGMENT
TABLEDW100HDUP(?
);数组中的数据是按增序排列的
DATADW?
COUNTDW0
DSEGENDS
;
---------------------------------------------------------------------
-----
CSEGSEGMENT
MAINPROCFAR
ASSUMECS:
CSEG,DS:
DSEG
START:
PUSHDS;设置返回DOS
SUBAX,AX
PUSHAX
MOVAX,DSEG
MOVDS,AX;给DS赋值
BEGIN:
MOVCX,100H;循环计数器
MOVSI,0
NEXT:
MOVDX,0
MOVAX,TABLE[SI]
COMP:
CMPTABLE[SI],AX;计算一个数的出现次数
JNEADDR
INCDX
ADDSI,2
LOOPCOMP
ADDR:
CMPDX,COUN;T此数出现的次数最多吗?
JLEDONE
MOVCOUNT,DX;目前此数出现的次数最多,记下次数
MOVDATA,AX;记下此数
DONE:
LOOPNEXT;准备取下一个数
MOVCX,COUNT;出现最多的次数存入(CX)
MOVAX,DATA;出现最多的数存入(AX)
RET
MAINENDP
CSEGENDS;以上定义代码段
;
---------------------------------------------------------------------
-----
ENDSTART
5.19数据段中已定义了一个有n个字数据的数组M,试编写一程序求出M中绝
5.20对值最大的数,把它放在数据段的M+2n单元中,并将该数的偏移地址存放在
M+2(n+1)单元中。
答:
程序如下:
DSEGSEGMENT
nEQU100H;假设n=100H
MDWnDUP(?
)
DATADW?
;M+2n单元
ADDRDW?
;M+2(n+1)单元
DSEGENDS
;
---------------------------------------------------------------------
-----
CSEGSEGMENT
MAINPROCFAR
ASSUMECS:
CSEG,DS:
DSEG
START:
PUSHDS;设置返回DOS
SUBAX,AX
PUSHAX
MOVAX,DSEG
MOVDS,AX;给DS赋值
BEGIN:
MOVCX,n;循环计数器
LEADI,M
MOVAX,[DI];取第一个数
MOVADDR,DI;记下绝对值最大的数的地址
CMPAX,0;此数是正数吗?
JNSZHEN;是正数,即为绝对值,转去判断下一个数
NEGAX;不是正数,变为其绝对值
ZHEN:
MOVBX,[DI]
CMPBX,0;此数是正数吗?
JNSCOMP;是正数,即为绝对值,转去比较绝对值大小
NEGBX;不是正数,变为其绝对值
COMP:
CMPAX,BX;判断绝对值大小
JAEADDRESS
MOVAX,BX;(AX)<(BX),使(AX)中为绝对值最大的数
MOVADDR,DI;记下绝对值最大的数的地址
ADDRESS