实验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进行精确反汇编
  使用g命令执行到程序退出执行之前(即源码文件中line16之前),观察结果。

1、对ex1.asm进行编译,连接,运行:

(1、使用masm进行编译,执行结果如图:

(2、使用link进行连接,执行结果如图:

(3、查看当前目录,可发现编译和连接生成的.obj文件和.exe文件,如图:(编译和连接过程中使用默认文件名)

(4、执行ex1.exe文件(运行在docbox中进行),运行结果如图::

2、使用debug工具对可执行文件进行调试:

(1、使用debug指令调试ex1.exe文件:

(2、使用d命令查看程序段前缀PSP所占的256个字节

(3、使用u命令进行反汇编:

 (4、使用g命令执行程序:

 (5、使用d命令查看程序修改的地址段的内容,如图

 使用g指令实行程序前:

 使用g指令实行程序后:

发现该段内存单元的值不是理论值,执行完成程序之后该段地址中前八个字节的数据应为:01 01 02 02 03 03 04 04,但查找结果与之不符。

(6、退出debug工具,使用cls命令清屏之后,再次执行程序,可看到在当前页面上出现特殊字符,再次查看该段地址的数据,发现数据与理论值相同

(7、再次运行,下图为页面内容滚动前和滚动后d指令查询结果,发现页面滚动后,查找结果就立刻发生变化

 

 

 结论:地址段A0000~BFFFF为显存地址空间,该段地址中数据发生变化在显示页面会做出响应(如本实验中出现特殊字符),随着页面内容的增多,

当页面内容滚动造成的当前显示页面内容的变化,对应的地址空间中的数据也会发生改变,也就是为什么在使用debug工具调试步骤中使用d指令查看

的数据数据不是理论值的原因。

二. 实验任务2
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

要求:

  使用masm、link对ex2.asm进行汇编、链接,得到可执行文件ex2.exe,运行并观察结果。
  使用debug工具对程序进行调试。
    结合可执行文件中寄存器CX的值,使用u命令对ex2.exe进行精确反汇编
    灵活使用t命令、p命令、g命令,对ex2.exe进行调试。(不一定要单步,有些地方可以用g命令,一次执行多行汇编指令)
    注意:单步调试时,对于循环指令loop, 中断指令int,使用t命令和p命令单步调试的区别。
  把ex2.asm中line9 mov cx, 4 改成mov cx, 8 ,保存后重新汇编、链接、运行并观察结果。
  结合上述实验和观察,分析、对比ex2.asm和ex1.asm,它们实现的是否是相同的功能和效果?在具体实现上有什么不同?

1、对ex2.asm进行编译,连接,运行:

  (1、编译

   (2、连接

 (3、运行:(在docbox中执行)

(4、修改:将ex2.asm中line9 mov cx, 4 改成mov cx, 8,运行结果如图:(在docbox中执行)

 可发现图标发现变化。

2、使用debug工具对可执行文件进行调试:

(1、使用debug指令调试ex2.exe文件:

 (2、使用u指令进行反编译:

 (3、使用g指令执行程序,并查看执行前后段地址B810中偏移地址0~F内容的变化:

 发现结果不是理论值。

 (4、再次使用debug工具进行调试:

执行一次循环,过程中页面内容未滚动,查看该段地址中的数据,发现数据被写入到该段内存地址中与理论值相同

继续调试,随着内容的增多,页面滚动,显存地址b810:0~f 所对应的显示页面上内容的变化,该段地址中存储的数据也发生变化

继续调试,循环执行完四次之后跳出循环,程序运行结束如图:

 回答问题:

结合上述实验和观察,分析、对比ex2.asm和ex1.asm,它们实现的是否是相同的功能和效?

  通过可执行文件ex1.exe和ex2.exe的运行结果来看,ex2.asm和ex1.asm执行的是相同的功能。ex1.asm是单独通过mov指令改

  写地址b810:0~f 中的内容,ex2.asm通过循环改写内容。 

三. 实验任务3
源代码

; ex3.asm
assume cs:code
    code segment
        mov ax, 0b800h
        mov ds, ax
        mov bx, 07b8h
        mov ax, 0237h
        mov cx, 8h
        s: mov [bx], ax
        add bx, 2h
        loop s
        mov ah, 4ch
        int 21h
    code ends
end

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

要求:把填充的字数据,从0237H 改成0239H,再次保存后,汇编、链接、运行,观察结果。
   把填充的字数据,从0237H 改成0437H,再次保存后,汇编、链接、运行,观察结果。
   猜测并分析,这个字数据中高位字节里存放的是什么信息,低位字节里存放的是什么信息。

(1、执行ex3.exe文件,执行结果如图:

2、修改程序中的数据:0237H 改成0239H,再次保存后,汇编、链接、运行,运行结果如图:

(3、修改程序中的数据:0237H 改成0437H,再次保存后,汇编、链接、运行,运行结果如图:

   使用debug调试产看写入的数据,如图:

 数据写入正确。

 

结论:三次测试,第一次填入的信息是:0237H;运行结果:7777777777777777(绿色)

        第二次填入的信息是:0239H;运行结果:9999999999999999(绿色)

        第三次填入的信息是:0437H;运行结果:7777777777777777(红色)

   通过对比:一、三低地址中内容相同,高地址不同,结果都为串7,颜色不同

   通过对比:一、二低地址中内容不同,高地址相同,结果颜色相同,显示的字符串不同

   可以猜测高地址存放的数据是显示字符的颜色对应的十六进制数,低地址存放的数据与是显示的字符对应的十六进制数(30~39对应0~9)

四. 实验任务4
程序源代码

; ex4.asm
assume cs:code
  code segment
    mov ax, 0h
    mov ds, ax
    mov bx, 200h
    mov ax, 0h
    mov cx, 64
    s: mov [bx], ax
    add bx, 1h
    add ax, 1h
    loop s
    mov ah, 4ch
    int 21h
  code ends
endq

要求:汇编、连接接无误后,灵活使用debug的t命令、g命令、p命令调试,用d命令查看0:200~0:23F,确认是否将0~63传送至此段内存区域。

1、对ex1.asm进行编译,连接,运行:(在docbox中进行)

(1、使用masm进行编译,执行结果如图:

 (2、使用link进行连接,执行结果如图:

 

2、使用debug工具对可执行文件进行调试:(调试在docbox中进行)

(1、使用debug指令调试ex4.exe文件

 (2、执行程序,在执行前后查看地址200~23f 中的的数据,执行结果如图:

 

 执行结果显示,地址200~23f 中的的数据数据发生改变,而且与理论值相同。

3、使用栈(编译连接过程跳过)

; ex4_1.asm
assume cs:code
    code segment
        mov ax, 1000h
        mov ss, ax
        mov sp, 0240h
        mov al, 00h
        mov ah, 01h
        mov cx, 64
        s0:push ax
        add ah, 2h
        add al, 2h
        loop s0    
        
        mov ax, 1020h
        mov ds, ax
        mov ax, 0h
        mov ss, ax
        mov sp, 0240h
        mov bx, 0h
        mov cx, 32
        s:push [bx]
        add bx, 2
        loop s

        mov ah, 4ch
        int 21h
    code ends
end

(1、调试ex4_1.exe程序,使用d指令查看程序执行前的地址段数据

 (2、执行程序

 (3、执行后查询地址段数据,数据被写入。

五. 实验任务5
源代码

; ex5.asm
assume cs:code      ;
    code segment
        mov ax,cs    ;cs指向程序存储的地址
        mov ax,0020H
        mov es,ax    ;es赋值数据存储的目标地址
        mov bx,0
        mov cx,20      ;一次只复制一个字节,需要循环20次
        S:mov al,[bx]  ;将数据取出传递到寄存器al中
        mov es:[bx],al  ;通过寄存器al将数据传递到目标地址中
        inc bx
        loop s
        mov ax,4c00H
        int 21h
    code ends
end

1、对ex5.asm进行编译,连接,运行:(在docbox中进行)

(1、使用masm和link对程序进行编译,连接,执行结果如图:

2、使用debug工具对可执行文件进行调试:(在docbox中进行)

(1、使用debug指令调试ex1.exe文件:

(2、调试前查看原地址的数据和目标地址段的数据,如图:

 (3、调试,给出一个循环的调试步骤,如图:

 (4、一个循环结束后再次查看目标地址的数据,如图:

 可以看到一个循环结束之后已经将一个数据存入到目标地址中。

(5、使用g指令执行程序,并在执行后查看原地址的数据和目标地址段的数据,如图:

运行结果显示,数据被正确的复制到目的地址段(前二十个字节)。

复制的是指令在内存中对应的编码。

起始位置的确定:CS寄存器是代码段寄存器,对应于内存中的存放代码的内存区域,用来存放内存代码段区域的入口地址(段基址)

第一个空:mov ax,____ 填入cs。

赋值的字节数量:机器指令在内存中以数据的形式存储,以字节为单位,首先随机填一个值通过mov指令传递给cx寄存器,使程序能够通过

编译和连接,在使用debug工具调试,使用u指令反编译查看车程序存储的地址单元,以此通过字节数来确定循环次数。在回头去更改程序。

2、实验总结

  (1)、注意事项:

      通过文本编辑器编写程序,程序中的十六进制数需要带上h,否则再执行过程中会被当成十进制数。

      通过文本编辑器编写程序,需要使用内存单元时不能直接使用“[偏移量]“的形式,需要通过寄存器来传递偏移量:[寄存器]

      编译、连接、调试文件后缀名问题:编译和连接时可以不带文件的后缀名,但是在使用debug命令调试时需要带上文件后缀名,否则执行报错

       (2)、可将程序分为两部分:伪指令和可执行代码段

    assume cs : 段名             (伪指令:将作用代码段和CUP中的段地址寄存器cs联系起来【如实验中使用的code只是一个标号】)

      段名 segment        (伪指令:段开始【和code ends 成对使用】)

        可执行代码段......

      段名 ends         (伪指令:段结束)

    end              (伪指令:汇编程序结束的标记)

    可执行代码段中包括程序的返回:mov ax, 4c00H      int 21H  (由这两条指令实现程序的返回功能)

posted @ 2020-11-05 13:51  3个月亮  阅读(455)  评论(4)    收藏  举报