微原软件实验二汇编语言程序设计Word文档格式.docx
《微原软件实验二汇编语言程序设计Word文档格式.docx》由会员分享,可在线阅读,更多相关《微原软件实验二汇编语言程序设计Word文档格式.docx(21页珍藏版)》请在冰豆网上搜索。
⑤习题4.21
图五:
习题4.21主程序&
子程序一流程图
图六:
习题4.21子程序二&
子程序三
3、源程序
datasegment
countequ256
dataends
stacksegmentstack'
stack'
bufdb20dup(?
)
stackends
codesegment
assumecs:
code,ds:
data,ss:
stack
start:
movax,data
movds,ax
xoral,al
movcx,count
zrbh:
movbh,16
next:
calldisp;
输出字符
pushax;
入栈保护
pushbx
callspace;
输出空格
popbx;
出栈恢复
popax
incal;
自增
decbh;
自减
jnzloop1;
如果输出个数还不是16的倍数
pushax
callcr;
输出回车、换行
popbx
movbh,16;
重新设置bh
loop1:
loopnext
movah,4ch
int21h
dispprocnear;
显示字符子程序
movdl,al;
在调用之前先把要显示的字符送入al
movah,2
ret
dispendp
spaceprocnear
movdl,20h
spaceendp
crprocnear
movdl,0ah
movdl,0dh
crendp
codeends
endstart
datasegment
org100h;
设置256个单元的起始地址偏移量为0100h
buf1db256dup(?
);
buf1的偏移量为0100h
countequ$-buf1;
得到buf1的长度
movax,data;
data=076Ah,数据段基址
movsi,offsetbuf1;
si=0100h
movcx,count;
循环计数
xoral,al;
al清零,初始化为00h
mov[si],al;
将al存储到ds*4+si=077A0h
incal;
al加一
incsi;
si加一
loopnext;
循环
movah,4ch;
程序结束
xorbx,bx;
bx置零,bl和bh分别存放正、负元素的个数
xordh,dh;
dh寄存器存放0元素的个数
重新将si指向buf1首地址
重新设定计数器
next2:
moval,[si];
将当前si对应位置的数据赋给al
cmpal,0;
比较al与0的大小,有符号数的比较参见笔记5.2.2
jgplus;
正数
jlnegat;
负数
jmpzero;
zero:
incdh;
0的个数加一
jmpnext3
negat:
incbh;
负数的个数加一
plus:
incbl;
正数的个数加一
next3:
incsi;
修改地址指针si
loopnext2;
循环
mov[si],dh
下移一个单元
mov[si],bx
buf1db259dup(?
buf1的偏移量为0100h,256个单元存放数据,3个单元存放结果
movcx,count-3;
next1:
将al存储到ds*16+si=077A0h
loopnext1;
重新设定计数器256=259-3
mov[si],dh
;
********************************以下为在屏幕上显示数据和统计结果
movcx,count;
重新设置计数器,注意这次计数器为259而非256
每行显示16个数据
next4:
将si对应的数据赋给al
movbl,al;
bl缓存al的数据
shral,1;
把数据右移4位,先处理高4位
shral,1
cmpal,09h;
判断高4位是字母还是数字
jbejia30;
若是数字0~9,加30H变为对应的ascii码
addal,7;
此处加7是因为一会要执行加30的操作,所以加起来就是加37h
jia30:
addal,30h
调用显示字符程序,显示高四位
moval,bl;
恢复原始数据,处理低四位
andal,0fh;
屏蔽高四位
判断低四位是字母还是数字
jbejia30a;
若是数字0~9
jia30a:
显示低四位
moval,20h;
两数据之间加一空格
calldisp
修改地址指针
loopnext5;
jmpstop
next5:
bh初始值为16
jnznext4;
当bh>
0时,转移到next4,处理下一个数据
moval,0ah;
每行够16个数据,送回车0ah,换行0dh
moval,0dh
jmpzrbh;
无条件转移到zrbh,继续处理下一行
stop:
msgdb'
ErrorNumber!
'
'
$'
crlfmacro;
定义宏指令,注意不要拼写错误
movdl,0dh;
送回车符
int21h;
dos调用,显示
movdl,0ah;
送换行符
endm
movax,segcode;
?
给数据段赋值,与代码段同在一个段
main:
callhexbin;
从键盘接收16进制数据,并转换成2进制
crlf;
回车换行宏指令
callbindec;
把2进制转换成10进制
jmpmain;
继续键入字符与转换
接收键盘键入的16进制数,并转换成2进制数子程序
hexbinprocnear
bx清零,存放键入的16进制数
newchar:
movah,01;
dos调用,接收键入的字符,赋给al
cmpal,0dh
jzretu;
若键入回车,则结束本组键入的数据
subal,30h;
对应于ascii的48
jzexit;
键入的字符小于0,为非法字符
cmpal,9
jleaddto;
键入的字符为0~9,转到移位处理
subal,07;
键入的字符大于9,判断是否为字母A~F
cmpal,0Ah
jlexit;
不是大于A的字母,为非法字符
cmpal,0fh
jgnext;
若大于字母F,再判断是否为小写字母a~f
addto:
movcl,4
shlbx,cl;
何时把字符赋给bx啦?
?
键入的字符左移4位,先键入的字符移向高位
movah,0;
难道第一次的没有值?
addbx,ax;
把刚刚键入的字符与前面的字符合在一起
jmpnewchar;
再接受新的字符
subal,20h;
判断是否为小写字母a~f,注意基址
cmpal,0Ah
若小于a(61H),则为非法字符
cmpal,0FH
若大于a小于f,则为字母a~f,转到移位处理
jgexit;
若大于字符f,则为非法字符
jmpretu;
此句不起作用?
exit:
调用回车换行宏指令
movdx,offsetmsg;
显示非法字符信息
movah,09
int21h
crlf
jmpnewchar
retu:
hexbinendp
把二进制数转换为十进制数子程序
bindecprocnear
movcx,10000;
因为键入的数最大为ffffh=65535,10000为十进制数?
calldec_div;
所以判断键入的数最大含有几个万位
movcx,1000;
键入的数含有的千位
calldec_div
movcx,100;
键入的数含有的百位
movcx,10;
键入的数含有的十位
movcx,1;
键入的数含有的个位
bindecendp
子程序的子程序
dec_divprocnear
movax,bx;
被除数的低16位在ax中
movdx,0;
被除数的高16位在dx中
divcx;
采用32位÷
16位
movbx,dx;
余数在dx中,送入bx
addal,30h;
商在al中,把其转变成ascii码
显示商al,即转换后的十进制数
dec_divendp
三、实验结果
图七:
附加题(格式输出ASCII码)运行截图
图八:
习题4.1运行截图
图九:
习题4.2运行截图
图十:
习题4.3运行截图
图十一:
习题4.21运行截图
四、实验总结
1、建议要求
可以考虑减少小作业次数,增加大作业,允许组队完成。
2、心得体会
此次编程用到了汇编的许多知识,比如各种结构,宏指令,子程序调用等等,同时也使我更加熟悉debug指令的调试。