微原软件实验二汇编语言程序设计.docx
- 文档编号:9227378
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:21
- 大小:152.39KB
微原软件实验二汇编语言程序设计.docx
《微原软件实验二汇编语言程序设计.docx》由会员分享,可在线阅读,更多相关《微原软件实验二汇编语言程序设计.docx(21页珍藏版)》请在冰豆网上搜索。
微原软件实验二汇编语言程序设计
北京邮电大学微机原理软件实验
专业:
信息工程
学生姓名:
×××
指导教师:
××
完成时间:
2013年11月25日
实验二:
汇编语言程序设计
1、实验目的
1、开始独立进行汇编语言程序设计;
2、掌握基本分支,循环程序设计;
3、掌握最简单的DOS功能调用
4、掌握最基本的代码转换方法;
5、运用子程序进行程序设计.
2、实验内容
1、实验要求
1、编写一个程序,在显示器上显示256个ASCII代码,要求显示格式为每行显示16个字符,两个ASCII字符之间空一格。
2、教材习题4.1、4.2、4.3
3、教材习题4.21
2、程序流程图
①附加题
图一:
附件题(格式输出ASCII码)流程图
②习题4.1
图二:
习题4.1流程图
③习题4.2
图三:
习题4.2流程图
④习题4.3
图四:
习题4.3流程图
⑤习题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
pushbx
callcr;输出回车、换行
popbx
popax
movbh,16;重新设置bh
loop1:
loopnext
movah,4ch
int21h
dispprocnear;显示字符子程序
movdl,al;在调用之前先把要显示的字符送入al
movah,2
int21h
ret
dispendp
spaceprocnear
movdl,20h
movah,2
int21h
ret
spaceendp
crprocnear
movdl,0ah
movah,2
int21h
movdl,0dh
movah,2
int21h
ret
crendp
codeends
endstart
②习题4.1
datasegment
org100h;设置256个单元的起始地址偏移量为0100h
buf1db256dup(?
);buf1的偏移量为0100h
countequ$-buf1;得到buf1的长度
dataends
stacksegmentstack'stack'
stackends
codesegment
assumecs:
code,ds:
data,ss:
stack
start:
movax,data;data=076Ah,数据段基址
movds,ax
movsi,offsetbuf1;si=0100h
movcx,count;循环计数
xoral,al;al清零,初始化为00h
next:
mov[si],al;将al存储到ds*4+si=077A0h
incal;al加一
incsi;si加一
loopnext;循环
movah,4ch;程序结束
int21h
codeends
endstart
③习题4.2
datasegment
org100h;设置256个单元的起始地址偏移量为0100h
buf1db256dup(?
);buf1的偏移量为0100h
countequ$-buf1;得到buf1的长度
dataends
stacksegmentstack'stack'
stackends
codesegment
assumecs:
code,ds:
data,ss:
stack
start:
movax,data;data=076Ah,数据段基址
movds,ax
movsi,offsetbuf1;si=0100h
movcx,count;循环计数
xoral,al;al清零,初始化为00h
next:
mov[si],al;将al存储到ds*4+si=077A0h
incal;al加一
incsi;si加一
loopnext;循环
xorbx,bx;bx置零,bl和bh分别存放正、负元素的个数
xordh,dh;dh寄存器存放0元素的个数
movsi,offsetbuf1;重新将si指向buf1首地址
movcx,count;重新设定计数器
next2:
moval,[si];将当前si对应位置的数据赋给al
cmpal,0;比较al与0的大小,有符号数的比较参见笔记5.2.2
jgplus;正数
jlnegat;负数
jmpzero;0
zero:
incdh;0的个数加一
jmpnext3
negat:
incbh;负数的个数加一
jmpnext3
plus:
incbl;正数的个数加一
next3:
incsi;修改地址指针si
loopnext2;循环
mov[si],dh
incsi;下移一个单元
mov[si],bx
movah,4ch;程序结束
int21h
codeends
endstart
④习题4.3
datasegment
org100h;设置256个单元的起始地址偏移量为0100h
buf1db259dup(?
);buf1的偏移量为0100h,256个单元存放数据,3个单元存放结果
countequ$-buf1;得到buf1的长度
dataends
stacksegmentstack'stack'
stackends
codesegment
assumecs:
code,ds:
data,ss:
stack
start:
movax,data;data=076Ah,数据段基址
movds,ax
movsi,offsetbuf1;si=0100h
movcx,count-3;循环计数
xoral,al;al清零,初始化为00h
next1:
mov[si],al;将al存储到ds*16+si=077A0h
incal;al加一
incsi;si加一
loopnext1;循环
xorbx,bx;bx置零,bl和bh分别存放正、负元素的个数
xordh,dh;dh寄存器存放0元素的个数
movsi,offsetbuf1;重新将si指向buf1首地址
movcx,count-3;重新设定计数器256=259-3
next2:
moval,[si];将当前si对应位置的数据赋给al
cmpal,0;比较al与0的大小,有符号数的比较参见笔记5.2.2
jgplus;正数
jlnegat;负数
jmpzero;0
zero:
incdh;0的个数加一
jmpnext3
negat:
incbh;负数的个数加一
jmpnext3
plus:
incbl;正数的个数加一
next3:
incsi;修改地址指针si
loopnext2;循环
mov[si],dh
incsi;下移一个单元
mov[si],bx
;********************************以下为在屏幕上显示数据和统计结果
movsi,offsetbuf1;重新将si指向buf1首地址
movcx,count;重新设置计数器,注意这次计数器为259而非256
zrbh:
movbh,16;每行显示16个数据
next4:
moval,[si];将si对应的数据赋给al
movbl,al;bl缓存al的数据
shral,1;把数据右移4位,先处理高4位
shral,1
shral,1
shral,1
cmpal,09h;判断高4位是字母还是数字
jbejia30;若是数字0~9,加30H变为对应的ascii码
addal,7;此处加7是因为一会要执行加30的操作,所以加起来就是加37h
jia30:
addal,30h
calldisp;调用显示字符程序,显示高四位
moval,bl;恢复原始数据,处理低四位
andal,0fh;屏蔽高四位
cmpal,09h;判断低四位是字母还是数字
jbejia30a;若是数字0~9
addal,7;此处加7是因为一会要执行加30的操作,所以加起来就是加37h
jia30a:
addal,30h
calldisp;显示低四位
moval,20h;两数据之间加一空格
calldisp
incsi;修改地址指针
loopnext5;循环
jmpstop
next5:
decbh;bh初始值为16
jnznext4;当bh>0时,转移到next4,处理下一个数据
moval,0ah;每行够16个数据,送回车0ah,换行0dh
calldisp
moval,0dh
calldisp
jmpzrbh;无条件转移到zrbh,继续处理下一行
stop:
movah,4ch
int21h
dispprocnear;显示字符子程序
movdl,al;在调用之前先把要显示的字符送入al
movah,2
int21h
ret
dispendp
codeends
endstart
⑤习题4.21
datasegment
msgdb'ErrorNumber!
','$'
dataends
stacksegmentstack'stack'
stackends
codesegment
assumecs:
code,ds:
data,ss:
stack
crlfmacro;定义宏指令,注意不要拼写错误
movdl,0dh;送回车符
movah,2
int21h;dos调用,显示
movdl,0ah;送换行符
movah,2
int21h;dos调用,显示
endm
start:
movax,segcode;?
?
?
?
?
给数据段赋值,与代码段同在一个段
movds,ax
main:
callhexbin;从键盘接收16进制数据,并转换成2进制
crlf;回车换行宏指令
callbindec;把2进制转换成10进制
crlf;回车换行宏指令
jmpmain;继续键入字符与转换
;接收键盘键入的16进制数,并转换成2进制数子程序
hexbinprocnear
xorbx,bx;bx清零,存放键入的16进制数
newchar:
movah,01;dos调用,接收键入的字符,赋给al
int21h
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;再接受新的字符
next:
subal,20h;判断是否为小写字母a~f,注意基址
cmpal,0Ah
jzexit;若小于a(61H),则为非法字符
cmpal,0FH
jleaddto;若大于a小于f,则为字母a~f,转到移位处理
jgexit;若大于字符f,则为非法字符
jmpretu;?
?
?
此句不起作用?
?
?
?
?
exit:
crlf;调用回车换行宏指令
movdx,offsetmsg;显示非法字符信息
movah,09
int21h
crlf
jmpnewchar
retu:
ret
hexbinendp
;把二进制数转换为十进制数子程序
bindecprocnear
movcx,10000;因为键入的数最大为ffffh=65535,10000为十进制数?
?
calldec_div;所以判断键入的数最大含有几个万位
movcx,1000;键入的数含有的千位
calldec_div
movcx,100;键入的数含有的百位
calldec_div
movcx,10;键入的数含有的十位
calldec_div
movcx,1;键入的数含有的个位
calldec_div
ret
bindecendp
;子程序的子程序
dec_divprocnear
movax,bx;被除数的低16位在ax中
movdx,0;被除数的高16位在dx中
divcx;采用32位÷16位
movbx,dx;余数在dx中,送入bx
addal,30h;商在al中,把其转变成ascii码
movdl,al;显示商al,即转换后的十进制数
movah,2
int21h
ret
dec_divendp
codeends
endstart
三、实验结果
①附加题
图七:
附加题(格式输出ASCII码)运行截图
②习题4.1
图八:
习题4.1运行截图
③习题4.2
图九:
习题4.2运行截图
④习题4.3
图十:
习题4.3运行截图
⑤习题4.21
图十一:
习题4.21运行截图
四、实验总结
1、建议要求
可以考虑减少小作业次数,增加大作业,允许组队完成。
2、心得体会
此次编程用到了汇编的许多知识,比如各种结构,宏指令,子程序调用等等,同时也使我更加熟悉debug指令的调试。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 软件 实验 汇编语言 程序设计