MCS8086习题4答案部分.docx
《MCS8086习题4答案部分.docx》由会员分享,可在线阅读,更多相关《MCS8086习题4答案部分.docx(21页珍藏版)》请在冰豆网上搜索。
MCS8086习题4答案部分
习题4答案:
1.从屏幕上输入大写字母,转换为小写字母并输出(生成.COM文件)
要求:
程序具有可读性、容错性
codesegmentpara
assumecs:
code,ss:
ss_seg,ds:
data
org0100H
mainprocfar
main1:
leadx,str1;显示提示信息
movah,9
int21h
movah,1;输入小写字母
int21h
cmpal,‘A’;判断输入字符是否为’a’~’z’
jberror
cmpal,‘Z’
jaerror
jmpnext
error:
leadx,str2;显示错误提示信息
movah,9
int21h
jmpmain1;跳转,重新输入
next:
addal,20h
pushax
leadx,str3;显示输出提示信息
movah,9
int21h
popax
movdl,al;显示转换后的大写字母
movah,2
int21h
movax,4c00h;返回操作系统
int21h
mainendp
str1db0dh,0ah,‘Pleaseinput(a-z):
$’
str2db0dh,0ah,‘Theinputiserror!
$’
str3db0dh,0ah,‘Theresultis:
$’
codeends
endmain
2.编写一子程序asc2bin,将ASCII转换为二进制数
要求:
输入参数:
AL中存放需要转换的ASCII
输出参数:
AL中存放转换后的二进制数并返回
;功能:
将ASCII转换为二进制数
;输入参数:
AL中存放需要转换的ASCII
;输出参数:
AL中存放转换后得到的二进制数
asc2binproc
subal,30h
cmpal,9
jbeasc2bin_1
subal,7
asc2bin_1:
ret
asc2binendp
3.内存中存放8个16位有符号数,求8个数值之和,并将结果存放在内存变量SUM中
注:
程序中应用到字扩展为双字的指令CWD
datasegmentpara
bufdw-1,30000,35000,36000,37000,20000,10000,-2
sumdd0
dataends
ss_segsegmentstack
dw100dup(0)
ss_segends
codesegmentpara
assumecs:
code,ds:
data,ss:
ss_seg
mainprocfar
movax,data
movds,ax
leabx,buf;bx指向buf首地址
movcx,8
main1:
movax,[bx]
cwd;有符号数字扩展为双字
addwordptrsum,ax;32位数相加
adcwordptrsum+2,dx
incbx
incbx
loopmain1;循环8次
movax,4c00h
int21h
mainendp
codeends
endmain
4.内存中存放8个8位有符号数,请按从大到小顺序排列
datasegmentpara
bufdb-1,30,35,36,37,20,100,-2
dataends
ss_segsegmentstack
dw100dup(0)
ss_segends
codesegmentpara
assumecs:
code,ds:
data,ss:
ss_seg
mainprocfar
movax,data
movds,ax
movcx,8
main1:
movbx,0;外循环
movdi,0
pushcx
main2:
moval,buf[bx];内循环
cmpal,buf[bx+1]
jgenext
xchgal,buf[bx+1];不符合规则,则交换数据
movbuf[bx],al
movdi,1
next:
incbx
loopmain2
popcx
cmpdi,0;判断内循环是否发生数据交换
jzexit
loopmain1
exit:
movax,4c00h
int21h
mainendp
codeends
endmain
5.内存中有8个16位数,请编写程序将8个数倒序排放
例:
定义内存中8个数bufdw100,3,1,20,40,-2,7,10
程序运行后,buf开始应为:
bufdw10,7,-2,40,20,1,3,100
datasegmentpara
bufdw-1,30000,35000,36000,37000,20000,10000,-2
dataends
ss_segsegmentstack
dw100dup(0)
ss_segends
codesegmentpara
assumecs:
code,ds:
data,ss:
ss_seg
mainprocfar
movax,data
movds,ax
movbx,0
movcx,8
main1:
pushbuf[bx]
incbx
incbx
loopmain1;8个数依次入堆栈
leabx,buf
movcx,8
main2:
pop[bx]
incbx
incbx
loopmain2;8个数依次出栈
movax,4c00h
int21h
mainendp
codeends
endmain
6.从键盘输入4位十进制数,然后以16进制形式显示在屏幕上.
例:
键盘输入:
1024屏幕上应显示:
0400H
要求:
键盘输入和显示结果时均应有提示
datasegmentpara
bufdb4dup(0)
vardw0
str1db0dh,0ah,‘Pleaseinputfournumbers(0-9):
$’
str2db0dh,0ah,‘Theinputiserror,pleasetryagain.$’
str2db0dh,0ah,‘Thehexresultis:
$’
dataends
ss_segsegmentstack
dw100dup(0)
ss_segends
codesegmentpara
assumecs:
code,ds:
data,ss:
ss_seg
mainprocfar
movax,data
movds,ax
main1:
leadx,str1;显示数据输入提示信息
movah,9
int21h
movbx,0
movcx,4;循环输入4个数
main2:
movah,1;DOS功能调用,输入数据
int21h
cmpal,‘0’;判断输入字符是否为’0’-‘9’
jberror
cmpal,‘9’
jaerror;若不为’0’-‘9’,则进行错误处理
subal,30h;ASCII转换为二进制,得到0-9
movbuf[bx],al;存入buf开始的缓冲区
incbx
loopmain2
jmpnext;数据输入正确后,跳转到后续处理
error:
leadx,str2;显示错误提示信息
movah,9
int21h
jmpmain1;跳转到重新输入
next:
movax,0;(((0*10+B3)*10+B2)*10+B1)*10+B0
movdx,0;得到输入的4位十进制数
movsi,10
movbx,0
movcx,4
main3:
mulsi;相乘后dx仍然保持0
movdl,buf[bx]
movdh,0
addax,dx
incbx
loopmain3;循环4次乘10
movvar,ax;得到的4位十进制数存放到var中
leadx,str3
movah,9
int21h;显示输出提示符
movch,4;以16进制显示输入的数据,循环4次
movcl,4
main4:
rolvar,cl;循环左移4位
movax,var
andax,000fh
callbin2asc;二进制转换为ASCII
callpchar;显示16进制
decch
jnzmain4
moval,‘H’
callpchar
movax,4c00h
int21h
mainendp
;功能:
将一个二进制数转换为ASCII
;输入参数:
AL中存放要转换的二进制数
;输出参数:
AL中存放转换后的ASCII
bin2ascproc
andal,0fh
addal,30h
cmpal,39h
jbebin2asc_1
addal,07h
bin2asc_1:
ret
bin2ascendp
;功能:
显示字符
;输入参数:
AL中存放要显示字符的ASCII
;输出参数:
无
pcharproc
movdl,al
movah,2
int21h
ret
pcharendp
codeends
endmain
7.数据段从100H开始存放字符串str1,从200H开始存放str2,二者均以NULL字符为结束符,编写程序将str2拷贝到str1末尾,形成一个完整字符串
例:
ORG100H
str1db0dh,0ah,‘Hello’,0
ORG200H
str2db‘Automation!
’,0
程序运行后结果应为:
str1db0dh,0ah,‘HelloAutomation!
’,0
datasegmentpara
ORG100H
str1db0dh,0ah,‘Hello’,0
ORG200H
str2db‘Automation!
’,0
dataends
ss_segsegmentstack
dw100dup(0)
ss_segends
codesegmentpara
assumecs:
code,ds:
data,ss:
ss_seg
mainprocfar
movax,data
movds,ax
moves,ax
leadi,str1;es:
di指向str1首地址
moval,0
cld;DF=0
repnzscasb;查找str1结束符NULL
decdi;找到str1结束符,并让es:
di指向该位置
leasi,str2;ds:
si指向str2首地址
main1:
lodsb;AL(ds:
si),si=si+1
stosb;(es:
di)AL,di=di+1
cmpal,0;判断是否到str2的结束符
jnzmain1
leasi,str1;ds:
si指向拷贝后的str1首地址
main2:
lodsb;显示拷贝后的str1字符串
cmpal,0
jzexit
callpchar
jmpmain2
exit:
movax,4c00h
int21h
mainendp
;功能:
显示字符
;输入参数:
AL中存放要显示字符的ASCII
;输出参数:
无
pcharproc
movdl,al
movah,2
int21h
ret
pcharendp
codeends
endmain
8.以10进制形式显示内存中一有符号字节数据
例:
vardb0ffH
屏幕应显示:
Theresultis:
-1
datasegmentpara
vardb7fh
str1db0dh,0ah,‘Theresultis:
’
bufdb4dup(‘’)
db‘$’
dataends
ss_segsegmentstack
dw100dup(0)
ss_segends
codesegmentpara
assumecs:
code,ds:
data,ss:
ss_seg
mainprocfar
movax,data
movds,ax
movbuf,‘+’
cmpvar,0;判断var是正数,还是负数
jgenext
movbuf,‘-‘
negvar;若var为负,则得到其相反数
next:
moval,var
movcx,3
movdl,10
leabx,buf+3
main1:
movah,0
divdl;(AX/10)商al
addah,30h;(AX/10)余数ah
mov[bx],ah
decbx
loopmain1;循环3次,分别得到百、十、个位
leadx,str1;显示10进制数
movah,9
int21h
exit:
movax,4c00h
int21h
mainendp
codeends
endmain
9.将一个16位的无符号数var,转换为非压缩格式BCD码,存放在内存中buf开始的单元中。
(按高位在前、低位在后的顺序存放)
datasegmentpara
vardw800H
bufdb5dup(0)
dataends
ss_segsegmentstack
dw100dup(0)
ss_segends
codesegmentpara
assumecs:
code,ds:
data,ss:
ss_seg
mainprocfar
movax,data
movds,ax
movcx,16;((0*2+B15)*2+B14)*2+…+)*2+B0
main1:
shlvar,1;得到var的Bi位
leabx,4
pushcx
movcx,5
main2:
moval,buf[bx];执行buf*2+Bi操作
adcal,al
AAA非压缩格式BCD码调整
movbuf[bx],al
decbx
loopmain2;内循环为5次
popcx
loopmain1;外循环为16次
exit:
movax,4c00h
int21h
mainendp
codeends
endmain
选作题:
10.内存中从str开始存放一字符串,结束符为NULL字符,请编写程序统计该字符串中单词的个数
例:
str1db0dh,0ah,‘Helloworld,welcometoDUT.CPUiscentralprocessingunit!
’,0h
统计’….’中的单词个数,结果为10
datasegmentpara
str1db'longlongago,therelivedaking,thekingaskedtheartistto’
db‘drawahorseforhim',0
wordsdw0
dataends
ss_segsegmentstack
db256dup(?
)
ss_segends
codesegment
assumecs:
code,ds:
data,ss:
ss_seg
mainprocfar
pushds
xorax,ax
pushax
movax,data
movds,ax
movcx,0;用cx存放单词数
leasi,str1
movbl,'';bl总保存当前字符的前一个字符
cld
main_3:
lodsb
andal,al;判断al是否为结束符0
jzmain_1
cmpal,'';比较是否是空格
jnzmain_2
main_4:
cmpbl,'';比较前一个字符是否为空格,不是则此空格
;不能算一个单词
jzmain_5
cmpbl,',';比较前一个字符是否为逗号,如果是则此空
;格也不能算一个单词
jzmain_5
inccx;只有当前字符为''或','而且前一个字符为有
;效字符时,才对单词数加1
jmpmain_5
main_2:
cmpal,',';比较是否是','号
jzmain_4
main_5:
movbl,al;进入这里表明此时al中内容不是0,'',','三种
;符号,保存al到bl
jmpmain_3
main_1:
cmpbl,'';判断结束符前面是否为单词,还是为一个''或','
jzmain_6
cmpbl,','
jzmain_6
inccx;若结束符前是一个有效字符,那么单词数应该加1
main_6:
movwords,cx
ret
mainendp
codeends
endmain
11编写程序用键盘1~7键,模拟7个音符,进行键盘演奏!
注:
需要对8253的定时器2和8255的PB口进行初始化
datasegmentpara
Table_Ldw131,147,165,175,196,220,247,262;低音1-7的频率
Table_Mdw262,294,330,349,392,440,494,523;高音1-7的频率
shift_1equ21h
shift_2equ40h
shift_3equ23h
shift_4equ24h
shift_5equ25h
shift_6equ5Eh
shift_7equ26h
shift_8equ2Ah
dataends
ss_segsegmentstack
db256dup(?
)
ss_segends
codesegment
assumecs:
code,ds:
data,ss:
ss_seg
mainprocfar
pushds;将psp+0h处段地址和偏移量压入堆栈以便返回OS
xorax,ax
pushax
movax,data;装载数据段寄存器ds,使之指向当前数据段
movds,ax
main_1:
movah,0;利用bios的16号中断,扫描键盘按键
int16h;AL中返回按键ASCII码,AH中返回按键扫描码
cmpal,0dh;判断是否为回车键,是回车键就退出
jzmain_exit
cmpal,'1'
jbmain_2
cmpal,'8'
jamain_2
andax,000fh;说明按下的是低音1-7,与操作将ASCII
;码转换到数字1-8
decal;将数值转换成以0开始的数字,以便从表中查找频率值
shlal,1;将数值乘以2,因每个频率值是字变量
leabx,Table_L
main_12:
movsi,ax
movdi,[bx+si];从表中取频率值
movbx,5000;发声时间
callGenSound
jmpmain_1
main_2:
cmpal,shift_1;判断是否按下shift+1键
jnzmain_3
movax,0
jmpmain_11
main_3:
cmpal,shift_2;判断是否按下shift+2键
jnzmain_4
movax,2
jmpmain_11
main_4:
cmpal,shift_3;判断是否按下shift+3键
jnzmain_5
movax,4
jmpmain_11
main_5:
cmpal,shift_4;判断是否按下shift+4键
jnzmain_6
movax,6
jmpmain_11
main_6:
cmpal,shift_5;判断是否按下shift+5键
jnzmain_7
mova