《汇编实验三(共18页).doc》由会员分享,可在线阅读,更多相关《汇编实验三(共18页).doc(18页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、精选优质文档-倾情为你奉上汇编语言程序设计 实验三 汇编语言程序调试运行学号: 姓名: (1)将下面的数据段输入,取名为1.asm, 保存在MASM文件夹下,生成.lst文件,不必连接运行,查看1.lst文件,试回答:DA1,DA2 的偏移量分别为多少?COUNT的值为多少?data segmentorg 20hnum1=8num2=num1+10hda1 db IBM PC da2 db 0ah,0dhcount equ $-da1data endsendDA1 偏移量为20,DA2偏移量为26,count值为8(2)输入下列指令,改正可能的错误(先不要运行程序):data segmentv
2、ar1 db 0, 25, 0DH,30var2 db 12h,0a4h,6bhvar3 db ABCDEFvar4 dw 1234h, 5678hvar5 dw 10h dup(?)data endscode segment assume cs:code, ds:databegin mov ax, data mov ds, ax lea si, var5 mov bx, offset var2 mov si, 0abh mov ax, var1+2 mov bx, si mov var5+4, var4 mov ah, 4ch int 21hcode ends end start正确代码:d
3、ata segmentvar1 db 0,25,0DH,255var2 db 12h,04h,6bhvar3 db ABCDEFvar4 dw 1234h, 5678hvar5 dw 10h dup(?)data endscode segment assume cs:code, ds:datastart:mov ax, data mov ds, ax lea si, var5 mov bx, offset var2 mov ax,0abhmov si,ax mov al,var1+2 mov ax,simov bx,ax mov ax,var4mov var5+4,ax mov ah,4ch
4、int 21hcode ends end start(3) 写一个完整的程序放在代码段C_SEG 中,要求把数据段D_SEG中的AGUEND和附加段E_SEG中的ADDEND相加,并把结果存放在D_SEG中的SUM中。其中AUGEND,ADDEND,SUM均为dw类型,AUGEND赋值为9251,ADDEND赋值为-5962。实验报告中要求写出源程序,简单叙述上机步骤,调试方法。a.实验步骤:1. 将 AGUEND、AGUEND+2分别存入AX,DX中。2与ADDEND、ADDEND+2相加后,将相加后的结果存入 SUM、SUM+2中。3. 以十六进制的形式显示结果。b.源程序:datas s
5、egment augend dd 9251 sum dd ?datas endse_seg segment addend dd -5962e_seg endscodes segment assume cs:codes,ds:datas,es:e_segstart: mov ax,datas mov ds,ax mov ax,e_seg mov es,ax mov ax,word ptr augend add ax,word ptr es:addend mov dx,word ptr augend+2 adc dx,word ptr es:addend+2 mov word ptr sum,ax
6、 mov word ptr sum+2,dx mov bx,word ptr sum+2 mov ch,4 mov dh,1AA: mov cl,4 rol bx,cl mov al,bl and al,0fh add al,30h cmp al,3ah jl print add al,07hprint: mov dl,al mov ah,2 int 21h dec ch jnz aa mov bx,word ptr sum mov ch,4 dec dh jz aa mov ah,4ch int 21hcodes ends end startc.显示结果: (4) 数组中是一组无符号数,将最
7、小数放在M单元中,经过汇编后,形成.EXE文件,先用G=0命令执行程序,用-D命令查看M单元的内容,会发现结果不正确。用单步执行命令T查找程序中的逻辑错误。DSEG SEGMENTMSG DB 13, 15, 7, 25, 24M DB ?DSEG ENDSCSEG SEGMENT ASSUME CS: CSEG, DS: DSEGSTART: MOV AX, DSEG MOV DS, AXMOV CX, 4MOV AL, MSG MOV SI, OFFSET MSG+1L1: CMP AL, SIJB NEXTMOV AL, SINEXT: LOOP L1MOV M, ALMOV AX, 4
8、C00HINT 21HCSEG ENDSEND START1. 程序说明:此程序的目的是要在13,15,7,25,24中找到最小数,并放在M单元。2. 调试说明:运行无问题3. 错误问题:结果中M单元的内容是错的,此时M为13,但真实值应为6.4.解决方法:该程序的循环是一个死循环,无法将每个数都进行比较,因此,需要每次循环时地址+1才能将每个数进行比较,所以需要在循环上加“INC SI”5.修改后程序DSEG SEGMENTMSG DB 13, 15, 7, 25, 24M DB ?DSEG ENDSCSEG SEGMENT ASSUME CS: CSEG, DS: DSEGSTART: M
9、OV AX, DSEG MOV DS, AXMOV CX, 4MOV AL, MSG MOV SI, OFFSET MSG+1L1: CMP AL, SIJB NEXTMOV AL, SINEXT: INC SI LOOP L1MOV M, ALMOV AX, 4C00HINT 21HCSEG ENDSEND START6.修改后运行结果:(5) 试编制一个汇编语言程序,求出首地址为DATA的10个无符号字数组中的最小偶数,把它存放在AX中。画出程序框图,写出源程序清单和执行结果。Data word 0141H, 0AE00H, 07B4H, 0A508H, 0691H,word 0870H,
10、 7542H, 0081H, 0916H, 0017Ha. 设计思路:本程序需要在10个无符号数中寻找最小的偶数,关键点为 最小和偶数,所以需要两次判断,最后把结果放在AX中。b. 程序设计图: c. 程序说明dseg segment data dw 0141H,0AE00H,07B4H,0A508H,0691H,0870H,7542H,0081H,0916H,0017H dseg ends cseg segment assume ds:dseg,cs:cseg start: mov ax,dseg mov ds,ax mov cx,9 /循环次数为9 mov ax,data /取data的首
11、地址放在ax中 mov si,offset data+2 /取data的第二号地址放在si中L1: test ax,01h / 判断ax中的数是奇数还是偶数 jnz L2 /不等于0即为奇数,跳到L2地址 test word ptr si,01h /判断si中的数是奇数还是偶数 jnz next /奇数跳到next地址 cmp ax,si /比较ax与si jb next /ax小于si,跳到next地址L2: mov ax,si /ax与si进行交换next: add si,2 /si+2,取下个数地址 Loop L1 / L1进行循环mov ax,4c00h / 退出int 21h cse
12、g ends end startd. 程序结果: (6) 有10个数,统计正数的个数,存放在变量M中。经过汇编后,形成.EXE文件,先用G=0命令执行程序,用-D命令查看M单元的内容,会发现结果不正确。用单步执行命令T查找程序中的逻辑错误,注意每一次循环中AL寄存器中的值变化是否正确(AL寄存器中存放正数的个数)DSEG SEGMENTMSG DB 4, -2, -6, 0, 5, 67, 8, -3, 5, 6M DB ?DSEG ENDSCSEG SEGMENT ASSUME CS: CSEG, DS: DSEGSTART: MOV AX, DSEG MOV DS, AXMOV CX, 1
13、0MOV AL, 0 LEA SI, MSGL1: MOV BL, SICMP BL, 0JBE NEXTINC ALNEXT: INC SILOOP L1MOV M, ALMOV AX, 4C00HINT 21HCSEG ENDSEND STARTa. 程序说说明这个程序的目的是要在4, -2, -6, 0, 5, 67, 8, -3, 5, 6中找出正数的个数。b. 调试说明:运行无问题。c. 错误问题:M单元中的内容错误,此时M为9,但真实值应为6.d. 解决方法:该程序不应用无符号数的跳转,因此,需要把JBE改为JLEe. 修改后代码:DSEG SEGMENTMSG DB 4, -2,
14、 -6, 0, 5, 67, 8, -3, 5, 6M DB ?DSEG ENDSCSEG SEGMENT ASSUME CS: CSEG, DS: DSEGSTART: MOV AX, DSEG MOV DS, AXMOV CX, 10MOV AL, 0 LEA SI, MSGL1: MOV BL, SICMP BL, 0JLE NEXTINC ALNEXT: INC SILOOP L1MOV M, ALMOV AX, 4C00HINT 21HCSEG ENDSEND STARTf. 修改后结果:(7) 假设有一组数据:5,-4,0,3,100,-51请编一程序,判断:每个数大于0,等于0,
15、还是小于0;并将最终结果存于以result为存储的字节单元中,(Result DB 6 dup(?))即: 1 当x0y= 0 当x=0 -1 当x0编程提示:1首先将原始数据装入起始地址为XX的字节存储单元中。2其中判断部分可采用CMP指令,得到一个分支结构,分别输出“y=0”, “y=1”, “y=-1”。将结果存入result的相应单元3程序中存在一个循环结构,循环6次,调用6次分支结构后结束。a.设计思路:该实验主要的两大步就是“与0比较”和“将结果存入result的相应单元”,因此,需要用指针来实现。b.程序代码:dseg segment msg db 5, -4, 0, 3, 10
16、0, -51 result db 6 dup(?) dseg ends cseg segment assume cs:cseg, ds:dseg start: mov ax,dseg mov ds,ax mov cx,6 /循环6次 lea si,msg /取msg的首地址放在si中 lea di,result /取result的首地址放在result中 l1:mov bl,si /把si的内容放入bl中 cmp bl,0 /比较bl与0的大小 jl l3 / bl小于0,跳到L3地址 cmp bl,0 /比较bl与0的大小 jg l4 /bl大于0,跳到L4地址 mov bl,0 /bl等于
17、0 mov di,bl /把bl的内容放在di中 jmp l2 /跳到L2中l3: mov bl,-1 /bl=-1 mov di,bl /把bl的内容放在di中 jmp l2 /跳到L2中l4: mov bl,1 /bl=1 mov di,bl /把bl的内容放在di中l2: inc si /si+1 inc di /di+1 dec cx /cx-1cmp cx,0jz done jmp l1done:mov ah,4chint 21hcsej endsend startc.运行结果:(8) 数据段中的三个字符,调用子程序将其逐个显示出来。子程序的功能是显示一个字符。单步执行,观察SP、I
18、P的变化,并用D命令查看栈顶的内容。DATA SEGMENTMAG DB ABCDATA ENDSSTACK_SEG SEGMENTDB 100 DUP(?)TOS LABEL WORDSTACK_SEG ENDSCODE SEGMENTASSUME CS:CODE, DS:DATA, SS: STACK_SEGSTART: MOV AX, STACK_SEGMOV SS, AXMOV SP, OFFSET TOSMOV AX, DATAMOV DS, AXMOV SI, 0MOV CX, 3LL: MOV DL, MAGSICALL MADDINC SILOOP LLMOV Ax, 4C00
19、HINT 21HMADD PROCMOV AH, 02HINT 21HRETMADD ENDPCODE ENDSEND STARTa.单步执行程序,如下:从图中可以看出,在执行call命令前,SP一直保持0064不变而IP持续增加。在RET前从上图中可以看出,当程序在SP、IP每次都是分别按2和1递增,当运行到RET时,SP还是按照2来递增,而IP缺减少了,说明指针回撤执行下一个循环。上图为 用d命令查看栈顶内容程序执行结果:(9) 将一个给定的二进制数按位转换成相应的ASCII码字符串,送到指定的存储单元,如二进制数转换成字符串为。要求将转换过程写成子程序,且子程序应具有较好的通用性,而必须
20、能实现对8位和16位二进制数的转换。(用寄存器或变量实现参数传递)测试数据:Var8bit byte B Var16bit word 00100B显示单元:Show8bit byte 8 dup (?) Show16bit byte 16 dup (?)程序代码:data segmentVar8bit db 93hVar16bit dw 0a3c4hShow8bit db 8 dup (?)Show16bit db 16 dup (?)data endscode segmentassume cs:code, ds:datamain procstart: mov ax,datamov ds,ax
21、mov dl,Var8bit;二进制数传给DXmov cx,8;置位数8lea si,Show8bit;字符串首址 sicall btrascii;调用子程序mov si,byte ptr 0dh;回车mov si+1,byte ptr 0ah;换行mov si+2,byte ptr $;结束符lea dx,Show8bitmov ah,9h;打印字符串int 21hmov dx,Var16bitmov cx,16lea si,Show16bitcall btrasciimov si,byte ptr 0dhmov si+1,byte ptr 0ahmov si+2,byte ptr $lea
22、 dx,Show16bitmov ah,9hint 21hmov ah,4chint 21hmain endpbtrascii proccmp cx,8;看cx是否为8jne l1mov dh,dl;将8位二进制数移到dx高8位l1:mov al,0rol dx,1;dx左循环一次,将当前最高位给CFrcl al,1;al带进位左循环一次,得到CF,即dx最高位add al,30h;将此位数转换成ascii码mov si,alinc siloop l1;循环cx次retbtrascii endpcode ends end start(10) 将一个给定的二进制数按位转换成相应的ASCII码字符
23、串,送到指定的存储单元,如二进制数转换成字符串为。要求将转换过程写成子程序,且子程序应具有较好的通用性,而必须能实现对8位和16位二进制数的转换。(用堆栈实现传参:可以选择用子过程来平衡堆栈,也可以用调用过程来实现平衡堆栈,程序功能说明中要指出)测试数据:Var8bit byte B Var16bit word 00100B显示单元:Show 8bit byte 8 dup (?) Show 16bit byte 16 dup (?)程序代码:data segmentVar8bit db 93hVar16bit dw 0a3c4hShow8bit db 8 dup (?)Show16bit d
24、b 16 dup (?)data endsstack segment dw 20 dup(?)tos label word;设置栈底,有无都可stack endscode segmentassume cs:code, ds:data, ss:stackmain procstart: mov ax,stackmov ss,axmov sp,offset tosmov ax,datamov ds,axmov ax,offset Var8bitpush axmov ax,8;置位数8push axmov ax,offset Show8bit;字符串首址 push axcall btrasciilea
25、 dx,Show8bitmov ah,9hint 21hmov ax,offset Var16bitpush axmov ax,16;置位数8push axmov ax,offset Show16bit;字符串首址 push axcall btrasciilea dx,Show16bitmov ah,9hint 21hmov ah,4chint 21hmain endpbtrascii procpush bpmov bp,sppush bxpush cxpush simov si,bp+8;二进制数mov bx,simov cx,bp+6;位数mov si,bp+4;目标地址cmp cx,8jne label1mov bh,bllabel1:mov al,0rol bx,1;bx左循环一次,将当前最高位给CFrcl al,1;al带进位左循环一次,得到CF,即dx最高位add al,30h;将此位数转换成ascii码mov si,alinc siloop label1;循环cx次mov si,byte ptr 0dh;回车mov si+1,byte ptr 0ah;换行mov si+2,byte ptr $pop sipop cxpop bxpop bpretbtrascii endpcode ends end start运行结果:专心-专注-专业
限制150内