汇编语言实验报告.docx
《汇编语言实验报告.docx》由会员分享,可在线阅读,更多相关《汇编语言实验报告.docx(95页珍藏版)》请在冰点文库上搜索。
汇编语言实验报告
实验一Masm6.11的使用方法
一、实验目的
1、创建一个新的汇编语言程序,熟练掌握汇编语言开发工具的使用方法,并对开发环境中一些坏境变量进行设置。
2、创建一个工程文件,对该工程文件进行编译,连接,并运行;
3、对建立的工程文件进行调试,在运行过程中查看各个寄存器的值,内存单元的值等。
二、实验环境
该试验包括的硬件和软件条件如下:
1、硬件环境
(1)INTELI3
(2)内存4g
2、软件环境
(1)WindowXPProfessorVMware虚拟机
(2)MASM6.11开发软件
三、实验步骤
1、将Masm6.11安装程序拷贝到D盘根目录下,并执行d:
\Masm611目录下Setup.exe文件,按照安装提示将程序安装到C盘根目录。
2、将C:
\masm611\Bin目录下的所有文件拷贝到C:
\Masm611\binr目录下,将C:
\Masm611\help目录下的所有文件拷贝到c:
\Masm61\binr目录下。
3、执行C:
\Masm611\Binr目录下的pwb.exe文件,打开开发环境。
4、在PWB编辑窗口中输入实验1.1中的程序,并保存为test.asm文件。
5、执行Project菜单下NewProject子菜单创建一个新的工程文件,并命名为test.mak,将test.asm文件加入到该工程文件中。
6、执行Project下Build子菜单编译连接该工程文件,并运行该可执行程序,观察程序执行的结果。
7、执行Run菜单下Debug子菜单,进入调试环境。
8、在程序的如下位置设置断点,并按要求观察寄存器堆栈或者内存单元的值。
Datasegment
Msgldb"pleaseinputthenumberofstudent:
$"
Numdb0
EnMsgdb0ah,0dh,'$'
Msg2db"pleaseinputthegradeofeachstudent:
$"
Msg3db"theaveragegradeofthesestudentis:
$"
avgdb0
ascavgdb0,0,'$'
Dataends
Stacksegmentparastack
db20hdup(0)
Stackends
codesegment
AssumeCs:
code,Ss:
stack,ds:
Data
Start:
movax,data
movds,ax
leadx,Msgl;此行设置断点,观察DS所指示的数据段的情况
movah,09h
int21h
CallNumproc;此行设置断点,观察屏幕输出,并观察堆栈的变化
movnum,bl;此行设置断点,观察bl的值,并观察堆栈的变化
leadx,EnMsg
movah,09h
int21h
leadx,Msg2
movah,09h
int21h
callAvgproc;此行设置断点,观察屏幕输出信息
leadx,EnMsg;此行设置断点,观察avg所对应的存储单元的值
movah,09h
int21h
leadx,Msg3
movah,09h
int21h
callbta;此行设置断点,观察屏幕输出信息
movah,4ch;此行设置断点,观察ascavg所对应的存储单元的值及屏
;幕输出信息
int21h
Numprocproc
pushax
pushcx
pushdx
leadx,EnMsg
movah,09h
int21h
movbl,0
lop1:
movah,01h
int21h;设置断点观察al寄存器的值
cmpal,0dh
jzlop2
cmpal,'0'
jllop1
cmpal,'9'
jalop1
subal,30h
movcl,al
moval,bl
movch,10
mulch
movbl,al;设置断点观察al寄存器的值
addbl,cl;设置断点观察bl寄存器的值
jmplop1
lop2:
popdx
popcx
popax
ret
Numprocendp
Avgprocproc
pushax
pushcx
xordx,dx;设置断点观察堆栈值的变化
movcl,num;设置断点观察cl寄存器的值
lop3:
callNumproc
xorax,ax
moval,bl
addax,dx
Divnum
addavg,al;设置断点观察avg存储单元的值
xordx,dx
movdl,ah
subcl,1
jnzlop3
popax
popcx
ret;设置断点观察堆栈值的变化
Avgprocendp
btaproc
pushax;设置断点观察堆栈值的变化
pushbx
xorax,ax
moval,avg
movbl,10
divbl
addah,30h;设置断点观察ax寄存器的值
addal,30h
movascavg,al;设置断点观察ascavg存储单元的值
movascavg+1,ah
leadx,EnMsg
movah,09h
int21h
leadx,ascavg;设置断点观察dx寄存器的值
movah,09h
int21h
popbx
popax
ret
btaendp
codeends
endstart
9、按照程序的执行过程绘制出程序流程图。
四、实验结果及其分析
1.安装MASM6.11:
双击setup.exe后按所给提示进行安装(基本上都是回车,中间不需要做什么更改),安装完成后将BIN和HELP文件夹里面的文件拷贝到BINR文件夹里面如图1.1所示。
所有安装工作完成之后打开PWB.exe集成开发环境应用程序。
2.在File菜单中单击New选项进入编辑源代码的界面,输入实验指导书中例1.2中的代码如图1.2所示:
图1.1
图1.2
3.保存上述文件,并建立工程文件,将上面的保存的文件作为该工程文件的一个文件:
在File菜单中单击Save选项,保存源代码为12.ASM文件,在Project菜单中单击NewProject选项建立新的工程名为aaa,并添加12.ASM文件,如图1.3所示.
图1.3
4.编译连接上述工程文件,并运行该程序:
在Project菜单中点击Rebuildall选项,如果没有错误,如图1.4所示,再点击RunPogram,进入运行界面运行程序得到运行结果如图1.5所示
图1.4
图1.5
5.调试上述程序。
调试工具:
debug32
(1)DS数据段的前后变化情况如下图
(2)调用21h号中断的9号子程序(屏幕输出程序)
后,屏幕输出情况及堆栈的变化情况如下图
(3)
Numproc:
调用21h号中断的1号子程序(键盘输入程序),输入3后,al寄存器的值如下
之后al寄存器和bl寄存器的值如下
第二次循环输入回车后al就存储了回车键的ASCII码,如图
后面的子程序调用Numproc的情况也大同小异,在此就不一一展示。
(4)从Numproc子程序返回后的堆栈的变化情况如下
可以看到IP出栈,同时bl的值为3
之后调用21h号中断的9号子程序后,幕输出情况
如下
(5)Avgproc:
开始时的堆栈情况,以及cl的值如下
然后接着转入了Numproc子程序。
在Numproc子程序中完成输入后,查看avg存储单元的值(共3此循环),分别如下
从Avgproc
子程序返回后,堆栈的变化情况如下
(6)从Avgproc子程序返回后,主屏幕输出信息和avg所对应的存储单元的值如下
(7)
将Msg3传入后调用21h中断的的9h号子程序,屏幕输出如下
(8)
bta:
查看堆栈情况,可以看到ip,ax,bx依次入栈
执行除法命令,将ax中的值(avg)除以10(0ah),并将商(十位)和余数(个位)分别存到al和ah中,然后分别加上30h以转换成ASCII码。
如下
然后将ax中的值传入ascavg的内存字中,如下
最后将ascavg内存字单元的偏移地址传入dx中,如下
(9)在子程序bta返回后,内存字单元ascavg的值如下
屏幕输出的结果信息如下
最后用21h中断的4ch子程序结束程序,调试完成。
6.程序的流程框图:
主函数流程图,如图1.13所示
开始
显示输入提示信息msg1
调用Numproc输入学生总数:
Num,并将Num由真值转换成对应的ASCⅡ
显示输入提示信息msg2
调用Avgproc,输入每个学生的成绩,并将平均成绩送给avg
调用bta,把avg的由ASCⅡ转换真值,并显示
结束
图1.13主函数流程框图
函数Numproc的流程图如图1.14Avgproc的流程图如图1.15所示
入口
入口
pushax;pushcx;
pushax;pushcx;pushdx
将num的值送给cl
显示回车换行
调用Numproc输入各个学生的成绩,并将每个成绩由字符类型转换成数字类型,除以num后累加给avg
输入一个字符到al
al=odh
N
Cl=C1-1
al<0
Y
Cl==0
N
al>9
Y
Y
popcx;popax
N
al-30h→cl
返回
bl→almovch10
图1.15
al*ch→al;al→bl
addbl,cl
popdx;popcx;popax
popdx
返回
图1.14
函数bta的流程图如图1.16所示
开始
pushax;pushcx;
对ax清零后将avg的值送给ax
movbl,10divbl
addah,30haddal,30h
movascavg,al
movascavg+1,ah
显示提示信息EnMsg
输出结果
返回
图1.16
5、结论
通过本次实验,我掌握了使用masm611去编译和连接一个汇编源程序的方法,并且学会了使用debug32进行调试、追踪。
熟悉了一些基本指令的使用方法,和一些基础的中断服务程序的使用方法。
并且掌握了十六进制数字转换成ASCII码的一种方法。
实验二比较两个字符串的大小
一、实验目的
本次实验主要达到如下目的:
1、进一步熟悉MSAM6.11软件的使用方法。
2、从键盘输入两个字符串,比较两个字符串的大小。
如果第一个字符串比第二个字符串大,则显示1;如果两个字符串相等,则显示0;如果第一个字符串比第二个字符串小,则显示-1.
二、实验环境
该试验包括的硬件和软件条件如下:
1、硬件环境
(1)INTELI3
(2)内存4g
2、软件环境
(1)WindowXPProfessorVMware虚拟机
(2)MASM6.11开发软件
三、实验步骤
1、画出实现上述功能的汇编语言程序流程图。
2、写出实现上述功能的汇编语言程序。
3、编译、连接编写的汇编语言程序,并运行生成的可执行文件,描述其执行情况。
4、对上述程序进行调试,比较反汇编后的程序和源程序的区别。
5、描述反编译后的程序在执行之前数据段的内容以及调试过程中各寄存器的变化情况和执行结束后数据段的内容。
四、实验结果及其分析
1、源代码:
assumecs:
code,ds:
data,ss:
stack
datasegment
msg1db"Pleaseinputthefirststring:
",0
msg2db"Pleaseinputthesecondstring:
",0
msg3db"Theresultis:
",0
resultdb3dup(0)
string1db100dup(0)
string2db100dup(0)
dataends
stacksegment
db32dup(0)
stackends
codesegment
start:
movax,stack
movss,ax
movsp,32
movax,data
movds,ax
leasi,msg1
callputs
leadi,string1
callgets
leasi,msg2
callputs
leadi,string2
callgets
leasi,msg3
callputs
leasi,string1
leadi,string2
callstrcmp
leasi,result
mov[si],ax
callputs
movah,0
int16h
movax,4c00h
int21h
;将字符串首地址通过si传入,字符串结束标志为ASCII0
putsproc
pushax
pushbx
movax,data
movds,ax
;取当前页号
movah,0fh
int10h
;用int10h的0eh号子程序显示字符
movah,0eh
cld
read:
lodsb
cmpal,0
jedone_read
int10h
jmpshortread
done_read:
;输出一个回车和换行
moval,0ah
int10h
moval,0dh
int10h
popbx
popax
ret
putsendp
;将存储首地址通过di传入,并在字符串末位添加结束标志ASCII0
getsproc
pushax
pushbx
pushcx
movcx,1
movax,data
moves,ax
;取当前页号
movah,0fh
int10h
cld
get_in:
;用int16h的0号子程序读键盘缓冲区,并显示字符
movah,0
int16h
cmpal,0dh
jedone_get_in
cmpal,08h
jebackspace
cmpal,20h
jbshortget_in
movah,0eh
int10h
stosb
jmpshortget_in
backspace:
;退格后清除光标处字符并使di减一
movah,0eh
int10h
movax,0a20h
int10h
decdi
jmpshortget_in
done_get_in:
;以ASCII0结束字符串,并输出一个回车和换行
xoral,al
stosb
movax,0e0ah
int10h
moval,0dh
int10h
popcx
popbx
popax
ret
getsendp
;用si和di分别传入两个字符串,按字典顺序比较,ax的值作为比较结果返回
strcmpproc
movax,data
movds,ax
moves,ax
cld
str_cmp:
;先看第一个字符串是否已到结尾,不结尾就和第二个字符串比较
movah,[si]
cmpah,0
jecmp_0
cmpsb
jabigger
jbsmaller
jmpshortstr_cmp
cmp_0:
;第一个字符串已到结尾,若第二个字符串不结尾则第一个串小,否则相等
moval,[di]
cmpah,al
jbsmaller
jmpshorteaqual
bigger:
movax,'1'
ret
smaller:
movax,'1-'
ret
eaqual:
movax,'0'
ret
strcmpendp
codeends
endstart
2、程序流程图如下
主函数流程图
开始
调用puts子程序,
显示第一条提示信息
调用gets子程序,
输入第一个字符串
调用puts子程序,
显示第二条提示信息
调用gets子程序,
输入第二个字符串
调用strcmp子程序,
比较两个字符串的大小
显示输出结果
结束
puts子程序流程图gets子程序流程图
入口
入口
保护用到的寄存器
保护用到的寄存器
获取当前显示页号
获取当前显示页号
从键盘缓冲区读取一个字符
读取一个字符并显示
否
否
回车?
是否读到字符串末尾?
否
指针减一,并删除屏幕上的字符
否
是
退格键?
是
是
显示换行,回车
否
恢复使用过的寄存器
是否为可打印字符?
出口
是
储存并回显
字符串末尾加入结束符
恢复使用过的寄存器
出口
strcmp子程序流程图
入口
是
第一个字符串是否到末尾?
否
比较两字符大小
第二个字符串是否到末尾?
否
是
大于?
movax,’0’
movax,’1’
否
否
小于?
是
movax,’1-’
出口
3、编译、连接汇编源程序,运行可执行文件,三次字符串比较的结果如下
第一次小于
第二次等于
第三次大于
4、程序调试结果如下
(1)反汇编后查看到的汇编代码如下
(2)初始情况的数据段的内容如下
(3)调用puts子程序后ip入栈,栈中内容如下
(4)puts子程序返回后屏幕输出如下
(5)调用puts子程序分别输入两个个字符串
(6)两个字符串在数据段中的存储情况如下
(7)调用strcpm子程序后,屏幕输出信息如下
(8)字符串比较结果由ax返回
(9)最后比较结果的输出信息如下
五、结论
通过这个实验我熟悉了子程序编写和调用的方法,并且熟悉了一些字符串处理指令和一些bios中断服务的使用方法,增加了调试程序并排除bug的经验。
实验三求学生名次
一、实验目的
本次实验主要达到如下目的:
从键盘输入若干个学生(总数不超过500)的姓名(英文字母不超过8个)及其5门课程的总成绩(百分制),输出任意名次的学生的姓名及其5门课程的总成绩(按总成绩的高低排序,总成绩最高者为第一名)
二、实验环境
该试验包括的硬件和软件条件如下:
1、硬件环境
(1)INTELI3
(2)内存4g
2、软件环境
(1)WindowXPProfessor虚拟机
(2)MASM6.11开发软件
三、实验步骤
1、画出满足上述要求的程序流程图
2、写出源程序及程序段说明
四、实验结果及其分析
1、源代码如下
assumecs:
code,ds:
data,ss:
stack
datasegment
msg1db"Pleaseinputthetotalnumberofstudents:
",0
msg2db"Pleaseinputtheinformationofeachstudent:
",0
msg3db"Pleaseinputtherankofastudent(input0exit):
",0
msg_namedb"name:
",0
msg_scoredb"score:
",0
totaldw0
numberdw0
studentstruc
this_namedb9dup(0)
this_scoredb4dup(0)
studentends
stu_arraystudent500dup(<>)
tempstudent<>
dataends
stacksegment
db128dup(0)
stackends
codesegment
start:
movax,data
movds,ax
moves,ax
movax,stack
movss,ax
movsp,128
leasi,msg1
callputs
leadi,total
callget_num
leasi,msg2
callputsln
leabx,total
movcx,[bx]
xorbx,bx
input_student:
leasi,msg_name
callputs
leadi,stu_array[bx].this_name
callgets
leasi,msg_score
callputs
leadi,stu_array[bx].this_score
callgets
addbx,13
loopinput_student
callsort_student
movcx,13
select:
leasi,msg3
callputs
leadi,number
callget_num
movax,[di]
cmpax,0
jeselect_null
decax
mulcl
movbx,ax
leasi,msg_name
callputs
leasi,stu_array[bx].this_name
callputsln
leasi,msg_score
callputs
leasi,stu_array[bx].this_score
callputsln
jmpshortselect
select_null:
movah,0
int16h
movax,4c00h
int21h
;将存储地址通过di传入
get_numproc
pushax
pushbx
pushcx
pushes
pushdi
movcx,1
pushcs
popes
leadi,buffer
;取当