汇编语言实验报告.docx
《汇编语言实验报告.docx》由会员分享,可在线阅读,更多相关《汇编语言实验报告.docx(14页珍藏版)》请在冰豆网上搜索。
![汇编语言实验报告.docx](https://file1.bdocx.com/fileroot1/2023-1/3/705294a5-04bc-40fb-8aee-5bd2e967e0be/705294a5-04bc-40fb-8aee-5bd2e967e0be1.gif)
汇编语言实验报告
汇编语言实验报告
实验一、汇编运行环境及方法、简单程序设计一、程序说明
本程序用来比较两个字符串string1和string2所含的字符是否相同。
若相同
’,否则显示‘Nomatch’。
则显示‘Match
在程序的数据段先定义两个字符串string1和string2,再定义两个字符串mess1
’和‘Nomatch’。
再代码段比较字符串string1和string2,和mess2,分别代表‘Match
通过比较判断是否相同。
若相同则显示‘Match’,否则显示
‘Nomatch’。
二、调试说明
再EDIT中建立ASM文件,再用汇编程序对源程序汇编产生目标文件Obj,再用连接程序产生执行文件EXE。
再用Debug进行调试。
其中常用到的指令有:
用-g命令来用运行程序,用-u命令来显示程序,用-d命令来查看数据段的情况,-e或-f命令来修改需要改正的部分,用-t指令来逐步执行程序,用-r指令来查看寄存用
器和修改寄存器的值,-q命令用来退出debug程序。
在这些命令的后面加上地址,可以将命令执行到相应的地方。
如用-g指令运行程序后,再用-u指令显示程序的执行借给如下:
若将string2改为'Movethecursorbackwards.',程序的其他部分不做改动,执行结果:
若将movcx,25语句改成movcx,24,结果为:
此时少做了一次循环,得到的结果就不正确了。
实验二、用DEBUG编程:
使用堆栈段将
AX和BX的内容进行交换等
一、程序说明
本实验包括两个部分,第一个部分是将AX和BX的内容进行交换,并用堆栈作为两寄存器交换内容的中间存储单元;第二部分是用DEBUG的命令将存储器偏移地
AH,0BH,0CH,0DH,0EH。
在DEBUG状态址300H,304H连续单元顺序装入0
下送入给出的程序中。
第一个程序先将AX的内容进栈,然后将BX的内容赋给AX,再将出栈的内容赋给BX即可。
第二个程序是在进入debug后,用-a指令输入给出的程序,然用-r指令安要求修改内存的内容,再用-t指令逐步执行每条指令,看修改的内存内容对指令执行结果的影响。
二、调试说明
第一部分先用-r指令修改ax,bx和sp的值,再用-a进行汇编,最后用-t单步执行。
执行情况及结果如下:
用debug调试后ax里的值为5000h,bx里的值为3000h。
第二部分先用-r修改bx和si的值,再用-e命令将存储器偏移地址300H,304H连续单
,0BH,0CH,0DH,0EH,再用-a汇编,输入代码,最后用-t单步执行。
元顺序装入0AH
执行结果如下:
用debug调试后ax中最后存放的数据为0E0D。
刚开始用-t单步执行时程序的前面几步没能执行,不知道是什么原因,后来发现用-a汇编时程序是从137a:
0100开始写的,而前面又用-t执行过两次,从0100到0105都已经被占用了,于是我就用-a137a:
0106,即从0106开始写代码,这样再用-t单步执行就能把程序的每一步的执行情况都显示出来了。
实验三、存储器块清零和内存块移动一、程序说明
第一个程序用来存储块清零,先设置块起始地址,然后设置块长度,再将当前地址内容清零,地址加一,然后判断是否清完,若清完则结束,否则返回到上一步。
第二个程序用来移动内存块,先设置块的源地址,再设置块的目标地址,然后设置移动长度,安长度重复传送数据直到结束。
二、调试说明
第一个程序在进入debug后,先用-u指令查看一下程序,再将断点设置在指令Loopagain之后,通过指令-g加上指令Loopagain后的地址,将程序运行到Loopagain之后停止,然后再通过-d指令查看相关内存内容是否被清零。
执行-g前:
执行-g后:
第二个程序在进入到debug后,先用-u指令查看一下程序,再将断点设置在指令repmovsb之前,通过指令-g运行后,然后用-d指令查看一下内存块的相关内容。
执行-g前:
执行-g后:
实验四、将键盘输入的小写字母用大写字母显示出来一、程序说明
本程序用来将小写字母转变为大写,并在屏幕上显示出来。
先利用DOS功能调用INT21H的1号功能从键盘输入字符,然后判断输入的是否是小写字母,若不是小写字母,则显示输入出错,重新输入。
若输入的是小写字母,则通过将其减去20h,从而变为大写字母。
在通过DOS功能调用INT21H的2号功能显示出来。
若输入的是Enter键,则结束程序。
二、调试说明
先用asm编写源程序,再汇编为obj文件,再连接成exe文件。
三、源程序清单和执行结果
DATASSEGMENT
string1db'error!
',0ah,0dh,'$'
string2db'$'
DATASENDS
STACK1SEGMENTPARASTACK
DW20HDUP(0)
STACK1ENDS
CODESSEGMENT
ASSUMECS:
CODES,DS:
DATAS,SS:
STACK1START:
movax,datas
movds,ax
L0:
movah,1
int21h
cmpal,0dh
jzexit
cmpal,'a'
jaeL1
jbL3
L1:
cmpal,'z'
jnaL2
jaL3
L2:
subal,20h
movcl,al
leadx,string2
movah,9
int21h
movdl,0
movdl,cl
movah,2
int21h
movdl,0ah
movah,2
int21h
movdl,0dh
movah,2
int21h
jmpL0
L3:
leadx,string1
movah,9
int21h
jmpL0
exit:
movah,4ch
int21h
CODESENDS
ENDSTART
执行结果:
实验五、循环程序设计一、程序说明
第一个程序是用来显示AL寄存器中的两位十六进位制数,通过DOS功能调用INT21H的2号功能显示出来。
第二个程序是用来判别键盘上输入的字符:
若是1-9字符,则显示之;若为A-Z或a-z字符,均显示“c”;若是回车字符,z则结束程序,若为其他字符则不显示,继续等待新的字符输入。
首先输入一个字符,将其和回车字符比较,若是回车字符,则结束程序。
1-9字符,则显示之。
若是若小于0,则重新等待输入。
若大于9,则跳转到和‘A’、Z’比较,若小于’A’,则重新等待输入,若大于’Z’,则跳转到和’a’、’z’比
较处,若小于a或大于z,则重新等待输入,否则输出‘c’。
二、调试说明
第一个程序执行结果:
可以对ax的值进行修改
用-r指令改变ax的值后,再用-g执行得到的结果不同,为修改后ax的值。
第二个程序执行结果:
实验六、分支程序设计
一、程序说明
第一个程序是用来显示AL寄存器中的两位十六进位制数,通过DOS功能调用INT21H的2号功能显示出来。
第二个程序是用来判别键盘上输入的字符:
若是1-9字符,则显示之;若为A-Z或a-z字符,均显示“c”;若是回车字符,z则结束程序,若为其他字符则不显示,继续等待新的字符输入。
首先输入一个字符,将其和回车字符比较,若是回车字符,则结束程序。
1-9字符,则显示之。
若是若小于0,则重新等待输入。
若大于9,则跳转
到和‘A’、Z’比较,若小于’A’,则重新等待输入,若大于’Z’,则跳转到和’a’、’z’比较处,若小于a或大于z,则重新等待输入,否则输出‘c’。
三、调试说明
第一个程序执行结果:
可以对ax的值进行修改
用-r指令改变ax的值后,再用-g执行得到的结果不同,为修改后ax的值。
第二个程序执行结果:
实验七、统计不同成绩段学生的人数
一、程序说明
本程序用来统计在不同分数段的学生人数并显示出来。
有两个子程序,分别用来
、统计各分数段的学生人数、输出相关内容。
子程序一中,先将每个学生的分数从10090、80、70、60逐个比较,在哪一分数段,则将其个数加一,直到所有分数都完成比较。
子程序二则利用DOS功能调用INT21H的9号功能在显示器上显示一个字符串和2号功能在显示器上显示一个字符来实现输出相关内容。
二、调试说明
在写程序的时候遇到了一些问题,主要是显示结果的子程序,由于是把统计的人数放在寄存器中,而数字是不能显示出来的,后来想到可以把数字转换为字符(加上30h),这样就可以显示了。
另外为了避免由于寄存器的值被修改而不能显示正确的结果,请教同学后,了解到可以对寄存器里的内容进行进栈出栈操作,这样就能够不用担心寄存器的值被修改了。
程序写好后,运行发现没能输出结果,刚开始以为是显示结果那部分出问题了,可是改了很久还是不能显示结果,后来又把前面的代码也看了,才发现是把movah,4ch那条语句中的ah误写成al了,改过来以后就能显示结果了,不过,显示的结果不正确。
看了程序,才知道是显示结果那个子程序有错误,由于是用寄存器来统计人数的,所以用了6个寄存器,写显示结果的子程序时没能把顺序理清楚,导致显示的结果不对,重新改了以后就得到正确的结果了。
三、程序框图
设置十个学生成
绩否
是
是否小于bh加1,di减1count是否60count减1为0
否是
是
退出程序是否小于bl加1,di减170count减190
否
是ch加1,di减1是否小于
count减180
80
否
是否小于cl加1,di减1是
90count减1
否
是是否小于dh加1,di减1100count减1
否al加1,di减1
count减1
四、源程序清单和执行结果datasegment
gradedb76,69,84,90,73,88,99,63,100,80
adb'<60renshu:
','$'
bdb0ah,0dh,'60~70renshu:
','$'
cdb0ah,0dh,'70~80renshu:
','$'
ddb0ah,0dh,'80~90renshu:
','$'
edb0ah,0dh,'90~100renshu:
','$'
fdb0ah,0dh,'100renshu:
','$'
countdb10dataends
stackssegment
stacksends
codesegment
assumecs:
code,ds:
data,ss:
stacks
mainprocfar
start:
movax,data
movds,ax
xorax,ax
xorbx,bx
xorcx,cx
xordh,dh
callcountgrade;调用子程序统计成绩
calloutput;调用子程序显示结果
movah,4ch
int21h
mainendp
countgradeprocnear
movdi,0
l0:
cmpgrade[di],60
jbl1
cmpgrade[di],70
jbl2
cmpgrade[di],80
jbl3
cmpgrade[di],90
jbl4
cmpgrade[di],100
jbl5
incal
jmpcontinue
l1:
incbh
jmpcontinue
l2:
incbl
jmpcontinuel3:
incch
jmpcontinuel4:
inccl
jmpcontinuel5:
incdh
jmpcontinuecontinue:
incdi
deccount
jnzl0
ret
countgradeendp
outputprocnear
movah,0
pushax
pushdx
pushcx
pushbx
leadx,a;输出小于60分的人数
movah,9
int21H
popbx
movdl,bh
adddl,30h
movah,2
int21H
leadx,b;输出60至69分的人数
movah,9
int21H
movdl,bl
adddl,30h
movah,2
int21H
leadx,c;输出70至79分的人数
movah,9
int21H
popbx
movdl,bh
adddl,30h
movah,2
int21H
leadx,d;输出80至89分的人数
movah,9
int21H
movdl,bl
adddl,30h
movah,2
int21H
leadx,e;输出90至99分的人数
movah,9
int21H
popbx
movdl,bh
adddl,30h
movah,2
int21H
leadx,f;输出100分的人数
movah,9
int21H
popbx
movdl,bl
adddl,30h
movah,2
int21H
ret
outputendp
codeends
endstart执行结果:
五、实验总结
刚开始觉得汇编语言很麻烦很难,因为有很多条指令,也不知道怎么样才能记住,
但经过几次实验,发现那些指令也不是很难,只要知道每条指令的用途就不会很难了。
实验的过程中也遇到了一些问题,遇到问题就看书或向同学请教,最后都解决了问题。
通过几次实验,我加强了对一些常用指令的理解,并对学习汇编语言有了一个更深的
认识。