ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

实验2 汇编源程序编写与汇编、调试

2020-11-02 10:33:59  阅读:241  来源: 互联网

标签:汇编 mov asm ax bx 源程序 调试


一、实验目的

1、理解并掌握汇编程序组成与结构

2、掌握汇编语言源程序编写→汇编→链接→调试的工具和方法

3、理解汇编程序中地址表示、段寄存器的用法

4、理解和掌握寄存器间接寻址方式[bx]

5、通过汇编指令loop的使用理解编程语言中循坏的本质

 

二、实验准备

1、学习/复习第5章使用[bx]和loop实现循坏的编程应用示例(教材5.5节,5.8节)

2、复习第3章“栈”的知识

3、结合第4章课件,复习完整汇编程序编写→汇编→连接→运行→调试的方法

4、复习8086汇编中内存单元地址的表示,以及段寄存器DS,SS,ES,CS的用途

 

三、实验结论

1、实验任务1

使用任意一款文本编辑器,编写8086汇编源程序ex1.asm。源代码如下:

;ex1.asm
assume cs:code
code segment
        mov ax, 0b810h
        mov ds, ax

        mov byte ptr ds:[0], 1
        mov byte ptr ds:[1], 1
        mov byte ptr ds:[2], 2
        mov byte ptr ds:[3], 2
        mov byte ptr ds:[4], 3
        mov byte ptr ds:[5], 3
        mov byte ptr ds:[6], 4
        mov byte ptr ds:[7], 4

        mov ah, 4ch
        int 21h
code ends
end

源程序编写完以后,使用masm、link对ex1.asm进行汇编、链接,得到可执行文件ex1.exe,并运行该可执行文件。该源程序的汇编、链接的命令以及运行结果的截图如下:使用debug加载可执行ex1.exe后,使用d命令查看程序段前缀PSP所占的256个字节,如下图所示:使用r命令查看寄存器,并结合可执行文件中寄存器CX的值,使用u命令对ex1.exe进行精确反汇编,反汇编的结果如下图所示:使用g命令执行到程序退出执行之前(即源代码文件中line16之前),观察结果。(程序的结果并未输出到显示器上)

 

2、实验任务2

使用任意一款文本编辑器,编写8086汇编程序ex2.asm。源代码如下:

 1 ; ex2.asm
 2 assume cs:code
 3 code segment
 4         mov ax, 0b810h
 5         mov ds, ax
 6 
 7         mov bx, 0
 8         mov ax, 101H
 9         mov cx, 4
10 s:    mov [bx], ax
11         add bx, 2
12         add ax, 101H
13         loop s
14 
15         mov ah, 4ch
16         int 21h
17 code ends
18 end

源程序编写完以后,使用masm、link对ex1.asm进行汇编、链接,得到可执行文件ex1.exe,并运行该可执行文件。该源程序的汇编、链接的命令以及运行结果的截图如下:使用r命令查看寄存器,并结合可执行文件中寄存器CX的值,使用u命令对ex2.exe进行精确反汇编,反汇编的结果如下图所示:灵活使用t命令/p命令、g命令,对ex2.exe进行调试。例如,先用t命令执行前2条指令,完成对DS的赋值;再用g命令进行调试,直接执行到CS:0016;此时,下一条指令即为循坏指令loop,所以使用p命令进行调试,跳过循坏体内部,直接得到循环的结果。执行过程的命令如下图:最后再用t命令执行程序返回的两条指令。重新调试这段源程序,并且最后用p命令执行中断指令int 21,发现执行后,显示出“Program terminated normally”,返回到debug中。执行结果如下图:把ex2.asm中line9mov cx,4改成mov cx,8,保存后重新汇编、链接、运行,所得结果如下图所示:

结合上述实验和观察,分析、对比ex2.asm和ex1.asm,它们实现的是否是相同的功能和效果?在具体实现上有什么不同?

由上述实验结果可知,ex2.asm与ex1.asm具有相同的功能和效果,都是向b810:0~7中写入了1 1 2 2 3 3 4 4,并在屏幕上输出4个相同的图案。不同的是ex1.asm是直接对显存地址进行赋值,而ex2.asm是通过寄存器间接赋值,并且对于多次重复的赋值操作,采用了loop用循环来实现。

 

3、实验任务3

 综合使用loop,[bx],编写完整汇编程序,实现向内存b800:07b8开始的连续16个字单元重复填充字数据0237H。汇编源程序如下:

assume cs:code
code segment
    
    mov ax,0b800h  ;在汇编源程序中,数据不能以字母开头,所以要在前面加0
    mov ds,ax
    
    mov bx,07b8h
    mov cx,16

s:    mov [bx],0237h
    inc bx
    inc bx
    loop s

    mov ax,4c00h
    int 21h

code ends
end

对该汇编源程序进行汇编和连接,如下图:

使用cls命令清屏后,运行该源程序,运行如下图:

把填充的字数据,从0237H改成0239H,再次保存后,进行汇编、连接和运行,结果如下图:

把填充的字数据,从0237H改成0437H,再次保存后,进行汇编、连接和运行,结果如下图:

 猜测并分析,这个字数据中高位字节里存放的是什么信息,低位字节里存放的是什么信息。

当填充的字数据为0237H时,运行结果是16个绿色的”7“;改变低位字节,把填充的字数据改成0239H后,运行结果是16个绿色的”9“,颜色没变,但数字变了。再改变高位字节,把填充的字数据改成0437H后,运行结果是16个红色的”7“,即数字没变,但颜色变了。所以猜测这个字数据的高位字节存放输出信息的颜色,低位字节存放输出信息的内容。在该猜测下,我先把填充的字数据改成0238H,运行结果如下:

发现改了低位字节后,运行结果果然是改变了输出信息的内容,没改变颜色。再改变高位字节,将填充的字数据改成0638H,运行结果如下:

 

4、实验任务4

 编写完整汇编源程序,实现向内存0:200~0:23F依次传送数据0~63(3FH)。汇编源程序如下:

assume cs:code
code segment
    
    mov ax,0020h
    mov ds,ax
    
    mov bx,0
    mov cx,64

s:  mov [bx],bx
    inc bx
    loop s

    mov ax,4c00h
    int 21h

code ends
end

源程序编写完成以后,进行汇编和连接,操作过程如下图:

然后用debug工具进行调试,用r命令查看寄存器,并根据寄存器CX的值对该程序进行反汇编。用g命令直接执行到循环之前:

再用p命令执行到循环结束。在程序退出之前,用d命令查看内存0:200~0:23F,确认是否将0~3F传送至此段内存中。结果如下图:

 选做:利用栈的特性,综合使用loop,push实现以上内容。

由于8086CPU的入栈操作是从高地址到低地址单元方向,所以入栈时从所传送数据的最大值开始,即应该将3fH最先进栈。又因为8086CPU的入栈和出栈操作都是以字为单位进行的,所以在传送数据的时候,必须将相邻的两个数据一起入栈。将3f3eH放到寄存器bx中,同时进栈,则接下来应该将3d3cH入栈,所以需要将bx的低8位寄存器bl和高8位寄存器bh都减2,依此类推。

汇编源程序如下:

assume cs:code
code segment
    
    mov ax,0020h
    mov ss,ax
    mov sp,0040h
    
    mov bx,3f3eh
    mov cx,64

s: push bx sub bl,2 sub bh,2 loop s mov ax,4c00h int 21h code ends end

对上面的源程序进行汇编和连接,再用debug工具进行调试。用r命令查看寄存器,并根据寄存器CX的值,对源程序进行反汇编:

直接用g命令执行到程序结束之前,再用d命令查看0:200~0:23f,确认将数据0~3F传送到此段内存区域中,查看结果如下图:

 

5、实验任务5

 完成教材实验4(3)(P121)

下面的程序的功能是将“mov ax,4c00h"之前的指令复制到内存0:200处,补全程序。上机调试,跟踪运行结果。

 1 assume cs:code
 2 code segment
 3     
 4     mov ax,cs
 5     mov ds,ax
 6     
 7     mov ax,0020h
 8     mov es,ax
 9 
10     mov bx,0
11     mov cx,17h
12 s:  mov al,[bx]
13     mov es:[bx],al
14     inc bx
15     loop s
16 
17     mov ax,4c00h
18     int 21h
19 
20 code ends
21 end

提示:

(1)复制的是什么?从哪里到哪里? (2)复制的是什么?有多少个字节?你如何知道要复制的字节的数量? 该程序实现的功能是将“mov ax,4c00h”之前的指令复制到内存0:200处,即复制从第4行开始到第16行结束的指令的机器码。由已给出的代码“mov ax 0020h”和“mov es,ax”可知,应该是用段寄存器es存放目标内存空间的段地址。那么要实现程序的复制,还需要获得代码段的段地址,所以代码“mov ax,____"和"mov ds,ax"应该是将代码段的段地址赋给段寄存器ds,因为代码段的段地址在cs中,所以该空应该填”cs“。寄存器cx中应该存放循环的次数,由于一开始不知道这段代码有多少个字节,所以可以先填”0“,然后将该源程序进行汇编和连接,再用debug工具进行反汇编,得到正确的机器码的字节数,再修改cx的值,具体操作如下图: 从以上的反汇编可知,该源程序有0017h个字节,所以cx的值为0017h。修改cx的值以后,重新对源程序进行汇编、连接,并用debug工具调试。 将源程序反汇编,并用g命令直接执行到中断程序之前,然后用d命令查看内存0:200中的内容,发现内存0:200中的前17h个字节中的内容已经变成了源程序的机器码。  

6、实验任务6(选做*)

 在Linux环境下,编写、汇编、运行、调试一个32位的Intel风格的x86汇编程序。

第1步,使用vim或其他任意文本编辑器,编写一个32位的Intel风格的x86汇编程序example.asm。

 1 ; example.asm
 2 
 3 global _start
 4 
 5 section .data
 6     msg db "a simple test", 0xa
 7     len equ $ - msg
 8 
 9 section .text
10 _start:
11     mov eax, 4
12     mov ebx, 1
13     mov ecx, msg
14     mov edx, len
15     int 0x80             ; 调用linux下的int 0x80中断的4号子功能,输出字符串
16 
17     mov eax, 1
18     mov ebx, 0
19     int 0x80             ; 调用linux下的int 0x80中断的1号子功能,退出

在Linux环境下,使用vim编辑器编写以上源程序,如下图:

 第2步,使用nasm,对example.asm进行汇编。

nasm -f elf32 example.asm

其中,选项-f表示指定目标文件格式。这里指定目标文件格式是elf32格式。

一开始用以上命令进行编译时,出现了错误example.asm:1:error:parser:instruction expected,后来发现是老师给的代码中用于定义全局变量的”global“打成了”glogal“,由于无脑抄代码,所以没有发现。修改以后,源程序就可以被成功编译了(上面截图的代码是修改前的,不想重新截图了)。

编译成功后,用ls命令查看目录中是否生成了目标文件example.o,编译及查看结果如下图:

第3步,使用ld,用example.o进行链接。

ld -m elf_i386 example.o -o example

其中,选项-m指定仿真模式。这里指定仿真Intel 32的模式。选项-o用于指定可执行文件的名称。这里指定生成的可执行文件名是example。

链接成功以后会生成可执行文件example,链接和用ls命令查看的结果如下:

注:第一次用ld进行链接时并没有成功,而是被系统提示sudo apt install binutils,后来查了一下知道ld是GNU binutils工具集下的一个重要工具,执行安装命令以后,就可以成功链接了。

第4步,执行可执行文件example。

./example

执行后,在shell命令终端查看返回值:

echo $?

执行结果和查看结果如下图:

echo $?的返回值是0,对应源码文件中line18寄存器ebx的值。

将example.asm中line18行中寄存器ebx的值改成别的数值,比如7。重新汇编、链接、运行。用echo $?查看返回值,发现这次返回值为7,如下图:

 

 

四、实验总结

 

 

标签:汇编,mov,asm,ax,bx,源程序,调试
来源: https://www.cnblogs.com/whr09/p/13903159.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有