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

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


 

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

要求:使用8086汇编程序编写、汇编、链接、运行、调试方法,对ex1.asm进行汇编、链接、运行,使用debug工具调试可执行文件。

  •  使用masm、link对ex1.asm进行汇编、链接,得到可执行文件ex1.exe,运行并观察结果。

      

   结果:屏幕右上方出现不同形状和颜色的图案。

  • 使用debug工具对程序进行调试。
    • 使用debug加载可执行文件ex1.exe后,使用d命令查看程序段前缀PSP所占的256个字节。

       

    • 结合可执行文件中寄存器CX的值,使用u命令对ex1.exe进行精确反汇编。

       用r命令查看CX的值为0031H,故使用u命令对ex1.exe进行精确反汇编结果如下:

       

    • 使用g命令执行到程序退出之前(即源码文件中line16之前),观察结果。

      由反汇编后的结果可知line 16 mov ah,4ch的偏移地址为002DH,故使用g命令执行结果如下:

      


 

2.实验任务2

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

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

    mov bx,0
    mov ax,101H
    mov cx,4
s:  mov [bx],ax
    add bx,2
    add ax,101H
    loop s
    mov ah,4ch
    int 21h
code ends
end

 要求:使用8086汇编程序编写、汇编、链接、运行、调试方法,对ex2.asm进行汇编、链接、运行,使用debug工具调试可执行文件。

  • 使用masm、link对ex2.asm进行汇编、链接,得到可执行文件ex2.exe,运行并观察结果。

    

   结果:屏幕右上方出现不同形状和颜色的图案。

  • 使用debug工具对程序进行调试。
    • 结合可执行文件中寄存器CX的值,使用u命令对ex2.exe进行精确反汇编。     

      使用r命令查看CX的值为001CH,故使用u命令对ex2.exe进行精确反汇编结果如下:

      

    • 灵活使用t命令、p命令、g命令,对ex2.exe进行调试。(不一定要单步,有些地方可以用g命令,一次执行多行汇编指令)

       t命令单步调试前四行:

      

      g命令调试到loop s之前:

       

      p命令单步调试到结束:

       

  • 把ex2.asm中line9 mov cx,4改成mov cx,8,保存后重新汇编、链接、运行并观察结果。

    

    结果:屏幕右上方的图案变多了。

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

    ex2.asm和ex1.asm他们实现的是相同的功能和效果,都是在屏幕的右上方打印4个图案(ex2.asm修改后打印8个图案),在具体实现上,ex1.asm是手动一行一行编写指令而ex2.asm则使用了loop循环。

 


 

3.实验任务3

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

  • 编写汇编源程序。
;ex3.asm
assume cs:code
code segment
    mov ax,0b800h
    mov ds,ax

    mov bx,07b8h
    mov ax,0237h
    mov cx,16
s:  mov [bx],ax
    add bx,2
    loop s

    mov ah,4ch
    int 21h
code ends
end
  • 运行结果截图。

     汇编、链接:

    

   清屏后运行:

    

  • 把填充的字数据,从0237H改成0239H,再次保存,汇编、链接、运行,观察结果。

   汇编、链接:

    

   清屏后运行:

    

   结果:显示的数字发生了改变。

  • 把填充的字数据,从0237H改成0437H,再次保存,汇编、链接、运行,观察结果。

    汇编、链接:

    

   清屏后运行:

    

   结果:显示的数字的颜色发生了改变。

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

    猜测:根据两次改变字数据:第一次改变低位字节,颜色不变显示的数字发生了改变,第二次改变高位字节,颜色发生改变显示的数字不变,猜想这个字数据中高位字节里存放颜色信息,低位字节里存放显示的内容信息。

 


 

4.实验任务4

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

必做:

  • 综合使用[bx]和loop,编写汇编源程序。
;ex4.asm
assume cs:code
code segment
    mov ax,0020h
    mov ds,ax

    mov bx,0
    mov cx,40h
s:  mov [bx],bl
    inc bx
    loop s

    mov ah,4ch
    int 21h
code ends
end
  • 灵活使用debug的t命令、g命令、p命令调试。在程序退出前,用d命令查看0:200~0:23F,确认是否将0~3F传送至此段内存区域

   编译、链接、进入debug:

   

   u命令反汇编:

    

   t命令单步调试前两行:

   

   g命令调试到loop s之前:

   

   p命令调试:

   

   在程序退出前,用d命令查看0:200~0:23F,确认是否将0~3F传送至此段内存区域:

   

   已经将0~3F送入此段内存区域。

选做:

  • 利用栈的特性,综合使用loop,push实现(限定仅使用8086中已学过的指令实现),编写源程序。
;ex4_2.asm
assume cs:code
code segment
    mov ax,0020h
    mov ss,ax
    mov sp,0040h

    mov bx,3f3eh
    mov cx,40h
s:  push bx
    add bh,-2
    add bl,-2
    loop s

    mov ah,4ch
    int 21h
code ends
end
  • 灵活使用debug的t命令、g命令、p命令调试。在程序退出前,用d命令查看0:200~0:23F,确认是否将0~3F传送至此段内存区域。

   编译、链接、进入debug:

   

   u命令反汇编:

   

   t命令单步调试前两行:

   

   g命令调试到loop s之前:

   

   p命令调试:

   

   在程序退出前,用d命令查看0:200~0:23F,确认是否将0~3F传送至此段内存区域:

   

   已经将0~3F送入此段内存区域。


 

5.实验任务5

教材实验4(3)(P121)

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

1.填空以后的源代码。

assume cs:code
code segment
    mov ax,code
    mov ds,ax
    mov ax,0020h
    mov es,ax
    mov bx,0
    mov cx,18h
s:  mov al,[bx]
    mov es:[bx],al
    inc bx
    loop s
    mov ax,4c00h
    int 21h
code ends
end

2.汇编链接后,灵活使用debug的t命令、g命令、p命令调试,用d命令查看0:200之后的若干字节,观察是否将mov ax,4c00h之前的指令复制到指定内存。

  • 截图

   编译、链接、进入debug:

   

   u命令反汇编:

    

   t命令单步调试前两行:

   

   g命令调试到loop s之前:

   

   p命令调试:

   

   用d命令查看076A:0之后的若干字节即指令的内容:

   

   用d命令查看0:200之后的若干字节:

   

   通过比较以上两幅截图的内容可知已将mov ax,4c00h之前的指令复制到指定内存。

  • 文字方式说明空白处填写依据

   第一空:需要把代码段内的指令当做数据复制到指定内存,源数据段与代码段code相同,故这里填了code。

   第二空:先随便填了一个小值(这里先填的是04h),编译连接后进入debug用r命令查看得CX的值为1DH,u命令反汇编后可知mov ax,4c00h之前的指令共占18h即24个字节,故第二空填18h。

 


 

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

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

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

;example.asm

global _start

section .data
    msg db "a simple test",0xa
    len equ $ - msg

section .test
_start:
    mov eax,4
    mov ebx,1
    mov ecx,msg
    mov edx,len
    int 0x80    ;调用linux下的int 0x80中断的4号子功能,输出字符串

    mov eax,1
    mov ebx,0
    int 0x80    ;调用linux下的int 0x80中断的1号子功能,退出

用vi编辑器编写程序后查看example.asm的内容:

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

 汇编后用ls命令查看,生成example.o文件:

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

链接后用ls命令查看,生成可执行文件example:

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

./example执行可执行文件:

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

显示返回值0,对应源码文件中line18寄存器ebx的值。

把example.asm中line18行中寄存器ebx的值7:

重新汇编、链接、运行:

再次使用 echo $? 查看返回值:

这次的返回值变成了7。

posted @ 2020-10-31 14:37  迟轩  阅读(441)  评论(4)    收藏  举报