1、 实验一 Masm6.11的使用方法一、实验目的1、创建一个新的汇编语言程序,熟练掌握汇编语言开发工具的使用方法,并对开发环境中一些坏境变量进行设置。2、创建一个工程文件,对该工程文件进行编译,连接,并运行;3、对建立的工程文件进行调试,在运行过程中查看各个寄存器的值,内存单元的值等。二、实验环境该试验包括的硬件和软件条件如下:1、硬件环境 (1)Intel Core Duo CPU P8700 (2)内存4G2、软件环境 (1)Window XP Professor (2)MASM6.11开发软件三、实验步骤 1、将Masm6.11安装程序拷贝到D盘根目录下,并执行d:Masm611目录下S
2、etup.exe文件,按照安装提示将程序安装到C盘根目录。 2、将C:masm611Bin目录下的所有文件拷贝到C:Masm611binr目录下,将C:Masm611help目录下的所有文件拷贝到c:Masm61binr目录下。 3、执行C:Masm611Binr目录下的pwb.exe文件,打开开发环境。 4、在PWB编辑窗口中输入实验1.1中的程序,并保存为test.asm文件。 5、执行Project菜单下New Project子菜单创建一个新的工程文件,并命名为test.mak,将test.asm文件加入到该工程文件中。 6、执行Project下Build子菜单编译连接该工程文件,并运行
3、该可执行程序,观察程序执行的结果。 7、执行Run菜单下Debug子菜单,进入调试环境。 8、在程序的如下位置设置断点,并按要求观察寄存器堆栈或者内存单元的值。Data segment Msgl db please input the number of student:$ Num db 0 EnMsg db 0ah,0dh,$ Msg2 db please input the grade of each student:$ Msg3 db the average grade of these student is:$ avg db 0 ascavg db 0,0,$Data endsStac
4、k segment para stack db 20h dup(0)Stack endscode segment Assume Cs:code,Ss:stack,ds:DataStart: mov ax,data mov ds,ax lea dx,Msgl ;1此行设置断点,观察DS所指示的数据段的情况 mov ah, 09h int 21h Call Numproc ;2此行设置断点,观察屏幕输出,并观察堆栈的变化 mov num,bl ;3此行设置断点,观察bl的值,并观察堆栈的变化 lea dx,EnMsg mov ah,09h int 21h lea dx,Msg2 mov ah,09
5、h int 21h call Avgproc ;4此行设置断点,观察屏幕输出信息 lea dx,EnMsg ;5此行设置断点,观察avg所对应的存储单元的值 mov ah,09h int 21hlea dx, Msg3 mov ah,09h int 21h call bta ;6此行设置断点,观察屏幕输出信息 mov ah,4ch ;7此行设置断点,观察ascavg所对应的存储单元的值及屏幕输出信息 int 21hNumproc proc push ax push cx push dx lea dx,EnMsg mov ah,09h int 21h mov bl,0 lop1: mov ah,
6、01h int 21h ;8设置断点观察al寄存器的值 cmp al,0dh jz lop2 cmp al,0 jl lop1 cmp al, 9 ja lop1 sub al,30h mov cl,al mov al,bl mov ch,10 mul ch mov bl,al ;9设置断点观察al寄存器的值 add bl,cl ;10设置断点观察bl寄存器的值 jmp lop1 lop2: pop dx pop cx pop ax retNumproc endpAvgproc proc push ax push cx xor dx,dx ;11设置断点观察堆栈值的变化 mov cl,num
7、;12设置断点观察cl寄存器的值lop3: call Numproc xor ax,ax mov al,bl add ax,dx Div num add avg,al ;13设置断点观察avg存储单元的值 xor dx,dx mov dl,ah sub cl,1 jnz lop3 pop ax ;14设置断点观察avg存储单元的值 pop cx ret ;15设置断点观察堆栈值的变化 Avgproc endp bta proc push ax ;16设置断点观察堆栈值的变化 push bx xor ax,ax mov al,avg mov bl,10 div bl add ah,30h ;17
8、设置断点观察ax寄存器的值 add al,30h mov ascavg ,al ;18设置断点观察ascavg存储单元的值 mov ascavg+1,ah lea dx,EnMsg mov ah,09h int 21h lea dx,ascavg ;19设置断点观察dx寄存器的值 mov ah,09h int 21h pop bx pop ax ret bta endp code ends end start 9、按照程序的执行过程绘制出程序流程图。四、实验结果及其分析 1、安装后的程序 图1.1安装成功2、将bin和help文件夹中的所有文件拷备到binr中 图1.2 Binr文件夹3、4开
9、PWB并建立t11.asm文件图1.3 建立t11.asm文件5、建立t11工程文件,并将t11.asm包含其中 图1.4 建立t11.mak 图1.5 将t11.asm添加到t11.ask中6、编译并运行 图1.6 编译成功 图1.7 运行结果7、进入调试环境 图 1.8 调试界面8、设置断点并观察 图1.9 设置断点界面(1)、lea dx,Msgl ;此行设置断点,观察DS所指示的数据段的情况图1.10 ds数据段地址及内容(2)、Call Numproc ;2此行设置断点,观察屏幕输出,并观察堆栈的变化 图1.11 屏幕输出 图1.12 堆栈变化 (3)mov num,bl 观察bl的
10、值并观察堆栈的变化 图1.13 bl02h 图1.14 堆栈变化(4)、call Avgproc ; 观察屏幕输出信息 图1.15 屏幕输出(5)、 lea dx,EnMsg ;5此行设置断点,观察avg所对应的存储单元的值 图1.16 avg对应的内存单元值03h (6)、call bta ;6此行设置断点,观察屏幕输出信息 图 1.17 屏幕输出(7)、 mov ah,4ch ;7此行设置断点,观察ascavg所对应的存储单元的值及屏幕输出信息图1.18 ascavg对应的内存单元值30h,33h 图 1.19 屏幕输出(8)、 int 21h ;8设置断点观察al寄存器的值1. al=E
11、Fh2. al=00h3. al=EFh4. al=00h5. al=01h6. al=00h图 1.20 ax寄存器 (9)、mov bl,al ;9设置断点观察al寄存器的值 al=00h al=00h al=00h图1.21 al值 (10)、 add bl,cl ;10设置断点观察bl寄存器的值 bl=00h bl=00h bl=00h图1.22 bl值 (11)、xor dx,dx ;11设置断点观察堆栈值的变化 图1.23 堆栈变化 (12)、 mov cl,num ;12设置断点观察cl寄存器的值图1.24 cl寄存器值00h (13)、 add avg,al ;13设置断点观察
12、avg存储单元的值 图1.25 输入第一个分数avg值为00h图1.26 输入第二个分数avg值为01h (14)、pop ax ;14设置断点观察avg存储单元的值 图1.27 avg值为03h (15)、ret ;15设置断点观察堆栈值的变化图1.28 堆栈变化 (16)、 push ax ;16设置断点观察堆栈值的变化 图1.29 堆栈变化 (17)、 add ah,30h ;17设置断点观察ax寄存器的值图1.30 ax寄存器值0300h (18)、mov ascavg ,al ;18设置断点观察ascavg存储单元的值图1.31 ascavg内存单元值ascavg存储单元的值为00h
13、、00h (19)、lea dx,ascavg ;19设置断点观察dx寄存器的值图1.32 dx寄存器 dx寄存器值为0025h9、程序流程图(1)主程序流程图 调用Dos 09系统将Msg1字符串输出到屏幕上开始调用子程序Numproc完成对学生数目的输入再调用09系统输出Msg2字符串调用子程序avgproc算出学生的平均成绩最后调用子程序bta将学生平均成绩ascII码化并输出结束 图1.33 主程序流程图(2)子程序流程图子程序Numproc的流程图:开始将ax,cx,dx压栈以保护数据,并进行回车换行调用Dos 01系统 输入一个十进制数(ASCII形式)Al=0dh ?Al=0Y将
14、十进制数-0转换成真值,经过相关处理并与后面输入的数构成正确的十进制数的形式,结果保留在bx中Dx,cx,ax出栈,返回主程序结束YNN图1.34 Numproc 流程图子程序bta的流程图:开始将ax,bx 入栈,把avg值赋给ax,让bl=10,然后执行div blAl,ah分别得到平均成绩的高位和低位,再分别将其+0转化成ASCLL形式分别赋给ascavg的低位和高位,最后输出结束图1.35 bta流程图子程序avgproc的流程图:开始将ax,cx入栈,dx清零,并把学生总数num赋给cl调用Numproc输入学生成绩,输入一个成绩后,将之赋给ax,便将其在下一次循环时加给ax,cl-
15、1=0Cx,ax出栈,返回主程序Ax加上dx, 除以num,将商加给avg,并把余数赋给dl,dh清零,dec cl结束NY图1.36 Avgproc流程图五、结论 刚开始接触汇编语言,从安装masm611,建立工程文件、编译、运行到调试,我遇到了很多问题,但都经过多次练习加以熟悉了,不过调试阶段还是有着一些小问题。通过这次实验,我对汇编语言的开发环境和其的开发过程有了一定的认识,也对 DOS 下的操作界面更加熟悉。但是,我觉得对该开发环境的使用开发还有待提高,要再花些时间用在如何调试功能上,希望在今后的实验中能够更加准确的掌握该软件的用法,能够很好的运用它的功能,总之这次实验还是很有收获的。
16、实验二 Masm6.11的使用方法一、实验目的1、了解汇编语言程序的基本结构。2、学习如何编写简单的汇编语言程序。3、学习汇编语言程序的各个段:数据段、堆栈段、代码段的作用。二、实验环境该试验包括的硬件和软件条件如下:1、硬件环境 (1)Intel Core Duo CPU P8700 (2)内存4G2、软件环境 (1)Window 7 (2)DOSBOX软件(3)MASM6.11开发软件三、实验步骤从键盘上输入两个字符串,比较两个字符串的大小,如果第一个字符串比第二个字符串大,则显示1;如果两个字符串相等,则显示0;如果第一个字符串比第二个字符串小,则显示-1。1.画出实现上述功能的汇编语言
17、程序流程图。2.写出实现上述功能的汇编语言程序。3.编译、连接编写的汇编语言程序,并运行生成的可执行文件,描述其执行情况。4.对上述程序进行调试,比较反汇编后的程序和源程序的区别。5.描述反编译后的程序在执行之前数据段内容以及调试过程中各寄存器的变化情况和执行结束后数据段的内容。 四、实验结果及分析1、程序流程图Repz cmpsb调用0a系统输入字符串str1(将其长度赋给bl)调用0a系统输入字符串str2比较str1和str2长度,将小的赋给cl,ch清0Cmp bl,str2JZ屏幕输出1屏幕输出 -1JBJAJa屏幕输出0JZ结束屏幕输出 -1JB开始 图2.1 程序流程图二.实验代
18、码data segmentMsg1 db input the first string:$Msg2 db input the second string:$Msg3 db the result is:$Msg db 0ah,0dh,24hstr1 db 100,0,100 dup(0)str2 db 100,0,100 dup(0)data endsstack segment para stackdb 20h dup(0)stack endscode segmentassume cs:code,ss:stack,ds:datastart:mov ax,datamov ds,axmov es,a
19、xlea dx,Msg1mov ah,09hint 21hlea dx,str1mov ah,0ahint 21hmov bl,str1+1lea dx,Msgmov ah,09hint 21hlea dx,Msg2mov ah,09hint 21hlea dx,str2mov ah,0ahint 21hlea dx,Msgmov ah,09hint 21hlea dx,Msg3mov ah,09hint 21hmov cx,0cmp bl,str2+1ja next1jna next2next1:mov cl,str2+1jmp lopnext2:mov cl,bljmp loplop:le
20、a si,str1+2lea di,str2+2repz cmpsbjz next3ja exit1jb exit2next3:cmp bl,str2+1ja exit1jb exit2jz exit3exit1:mov dl,1mov ah,2int 21hjmp enddexit2:mov dl,-mov ah,2int 21hmov dl,1mov ah,2int 21hjmp enddexit3:mov dl,0mov ah,2int 21hendd:mov ah,4chint 21hcode endsend start三、编译、连接编写的汇编语言程序,并运行生成的可执行文件,描述其执
21、行情况。程序执行情况 图 2.2 执行结果四、调试4.对上述程序进行调试,比较反汇编后的程序和源程序的区别。(一)进入调试环境 图2.3 调试界面(二)反汇编后的程序和源程序的区别1、 图2. 4 Data值被05EF内存地址代替2、 图2.5 变量Msg1用其所在内存的偏移值代替3、 图2.6 str变量用其所在内存的偏移值代替4、 图2.7 在源程序所对应的代码结束后额外增加的反汇编代码五、数据段内容以及各寄存器的变化情况1、程序执行前数据段内容 图2.8 数据段内容2、寄存器的变化 执行前: 图2.9 寄存器值输入第一个字符串: 图2.10 屏幕显示和寄存器值 图2.11 str1内存段
22、值的变化输入第二个字符串:图2.12 屏幕显示和寄存器值 图2.13 str2内存段值之变化 图2.14 运行CMP 图2.14跳到lop3 图2.15 循环repz cmpsb 图2.16 循环后程序结束后: 图2.17 数据段内容六、结论首先我对汇编程序有了更深的了解,如指令格式,变量定义,各种指令编写和使用等等,其次调试过程也变得得心应手,寄存器值和代码段值得变化能与程序的执行联系起来,不过最大的收获还是对一些比较指令、转移指令、和循环指令以及字符串比较指令的理解和使用,不过,对其他指令的学习也亟待需要。实验3 程序的基本结构一、实验目的1、学习用结构体编写汇编语言程序,会熟练运用汇编语
23、言提供的指令来实现任意形式的程序设计逻辑结构:顺序,循环及分支等。2、能够比较熟练地写出实验的源程序,并且对程序段有一定的认知和了解。3、进一步熟练流程图的画法和实验报告的书写。二、实验环境该试验包括的硬件和软件条件如下:1、硬件环境 (1)Intel Core Duo CPU P8700 (2)内存4G2、软件环境 (1)Window 7 (2)DOSBOX软件(3)MASM6.11开发软件三、实验步骤根据实验的要求画出实验的流程图,实验要求如下:从键盘输入若干个学生(总数不超过500人)的姓名(英文字母不超过8个)及5门成绩的总成绩(百分制),输出任意名次的学生的姓名及其5门课程的总成绩(
24、按总成绩高低排序,总成绩最高者为第1名)。要求:(1) 画出满足上述要求的程序流程图(2) 写出源程序及程序段说明(3) 写出满足上述要求的实验报告四、实验结果及其分析(1)主程序流程图1、Numproc流程图开始调用01系统输入十进制数(ASCII形式)是否回车Al=0Al-al-0ah-0,Temp-ax,ax-ax*10+bxBx-ax+temp结束YNNY 图3.1 Numproc流程图2、input流程图开始调用Numproc输入istbx-score,tenstubx-score,cx-numCx=0对list中的数采用冒泡排序dihe结束NY排序开始Cx-num,dec cxCx
25、入栈,j-0,jj-1si=j*2,di=listdi交换listsi和listdi的值Inc j,inc jj排序结束NYCx=0?NCx出栈Cx=0?NYY图3.2 input流程图3、output流程图开始调用Numproc输入要查找的名次bx-(bx-1)*2,x=0相等将对应学生的信息输出比较listbx和tenstux.s的大小Inc XNY结束 图3.3 output流程图(2)实验代码及程序段说明data segmentMsg1 db input the n:$Msg2 db input the scores:$Msg3 db input the name:$Msg4 db i
26、nput the position:$Msg5 db name is:$Msg6 db score is:$Msg db 0ah,0dh,24hnum dw ?stu struct ;学生结构体n db 9,0,9 dup(0);姓名最多8个字符,第9个存放字符串结束字符$s dw ? ;成绩stu endstemp dw ?i dw -1j dw 0jj dw 1tenstu stu 10 dup(,10);定义十个学生的结构体变量,容量可以改变list dw 10 dup(0);先存放学生原始输入成绩,后存放冒泡排序后的成绩score dw ?result db 0,0,0,24h;用于成
27、绩的输出,成绩最高为三位数data endsstack segment para stackdb 200 dup(0)stack endscode segmentassume cs:code,ss:stack,ds:datastart:mov ax,datamov ds,axlea dx,Msg1mov ah,09hint 21hcall Numproc;输入学生个数mov num,bxlea dx,Msgmov ah,09hint 21hcall Input;输入学生成绩并排序mov cx,numlopp:call output ;学生人数为循环次数,依次输出要选择的学生信息loop lop
28、pmov ah,4chint 21h;主程序结束Numprocprocpush cxmov bx,0lop1:mov ah,01hint 21hcmp al,0dhjz enddcmp al,0jb lop1cmp al,9ja lop1and al,0fhmov ah,0mov temp,axmov ax,bxmov cx,10mul cxmov bx,tempadd bx,axjmp lop1endd:pop cxretNumproc endpInput procmov cx,numlop2:push cxinc ilea dx,Msg2mov ah,09hint 21hcall Nump
29、roc;输入成绩mov score,bxmov ax,imov dl,0dhmul dlmov bx,axmov ax,scoremov tenstubx.s,ax;将成绩赋给相应对应的学生mov ax,imov cl,2mul clmov bx,axmov ax,scoremov listbx,ax;并一同存储到数组list中lea dx,Msgmov ah,09hint 21hlea dx,Msg3mov ah,09hint 21hmov ax,imov dl,0dhmul dlmov bx,axlea dx,tenstubx.nmov ah,0ahint 21hmov tenstubx.
30、n+9,24hlea dx,Msgmov ah,09hint 21hpop cxloop lop2;循环输入lea dx,Msgmov ah,09hint 21hjmp sort;对list数组中的成绩进行冒泡排序sort: ;排序开始mov cx,numdec cxcmp cx,0jz endd1lop11:push cxmov j,0mov jj,1lop22:mov ax,jmov bl,2mul blmov si,axmov ax,jjmov bl,2mul blmov di,axmov ax,listsicmp ax,listdijge nextxchg ax,listdixchg
31、ax,listsinext:inc jinc jjnext3:loop lop22pop cxloop lop11endd1:ret ;排序结束Input endpoutput proc ;学生信息输出push cxlea dx,Msg4mov ah,09hint 21hcall Numprocmov ax,bxdec axmov dl,2mul dlmov si,axmov j,0lop4:mov ax,jmov dl,0dhmul dlmov bx,axmov ax,tenstubx.s;将要查找名次学生的成绩与结构体中的学生成绩比较lop3:cmp ax,listsijz next1;两
32、者相等则输出信息inc j ;否则与结构体下一位的成绩进行比较,依次循环jmp lop4next1:lea dx,Msg ;信息输出mov ah,09hint 21hlea dx,Msg5mov ah,09hint 21hlea dx,tenstubx.n+2mov ah,09hint 21hlea dx,Msgmov ah,09hint 21hlea dx,Msg6mov ah,09hint 21hmov ax,tenstubx.smov cl,10div cladd ah,30hmov result+2,ahmov ah,0div cladd ax,3030hmov result,almo
33、v result+1,ahlea dx,resultmov ah,09hint 21hpop cxlea dx,Msgmov ah,09hint 21hretoutput endpcode endsend start(三)实验结果与分析1.结果界面 图3.4 运行结果2.调试界面 输入人数2个,05EF:0063可看出num=0002,同时输入123,234,在05EF:00EF和05EF:00F1可观察到list中两数的十六进制形式,分别为007B和00EA图3.5 排序前list数组中的值分配情况排序后:可观察到list数组中的两个数位置交换,由大到小排序图3.6 排序后list数组中的值
34、分配情况五、结论通过本次试验,我收获颇大。首先对结构体变量有了一定的认识和练习,知道数组下标需用指针寄存器表示,结构体数组下标值要经过如此操作mov ax,I mov bl,0dh,mul bl,mov bx,ax才能正确使用,对其中缘由,我还要经过进一步学习,然后就是对汇编程序中冒泡排序的使用,编写过程中,总是运行错误,不过在调试中找到了原因所在,纠正了错误后,果断运行成功了。由此看来,我还要多加练习。实验4 子程序和堆栈一、实验目的 1、了解程序的模块性,初步学习和掌握模块的应用。2、初步学会子程序的应用。二、实验环境该试验包括的硬件和软件条件如下:1、硬件环境 (1)Intel Core
35、 Duo CPU P8700 (2)内存4G2、软件环境 (1)Window 7 (2)DOSBOX软件(3)MASM6.11开发软件三、实验步骤 某单位在计算工作量时采用:工作量=工作时间(小时)*系数计算员工的工作量。其中工种不同其系数也不一样,该单位的不同工种(不大于100),请从键盘上输入每个工人一年的工作时间(按小时计算,精确到小数点后1位)以及该工人的工种所对应的系数(精确到小数点后2位),求该单位所有员工(不超过1000人)一年的工作量。1、对上述问题进行分析,写出分析报告及相关算法。2、写出各个模块的说明。3、画出各个模块的流程图。4、画出各个模块之间的调用关系5、写出实现功能
36、的汇编语言程序。6、写出满足上述要求的实验报告。四、实验结果及其分析(1)分析:本程序由三部分组成:输入员工数量;输入每个员工的工作时间和系数并相乘求和;显示所有员工的一年的总工作量。在输入部分,须将十进制数ASCII码转换成十进制数,同时由于可能存在小数,而对于工作时间小数位数为1位,系数应输入到小数点后三位,而子程序Numproc均将其变成相应的整数,即 工作时间变成原来的10倍,系数贬称原来的100倍。由于所有员工的的总工作量可能超过65535,应采用32位寄存器,而由前面所说,员工的总工作量变成实际的1000倍,而实际结果要保留三位小数,因此将其除以10,得到整数部分,输出时,再将十进制数转换成相应的十进