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

一、实验目的

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的用途。

三、实验内容 

为了偷懒省去排版的精力,实验内容请详见实验二实验指导pdf文件。

四、实验结论 

1. 实验任务1

此部分书写内容:

ex1.asm源代码

 1 ;ex1.asm
 2 assume cs:code
 3 code segment
 4      mov ax, 0b810h
 5         mov ds, ax
 6         mov byte ptr ds:[0], 1
 7         mov byte ptr ds:[1], 1
 8         mov byte ptr ds:[2], 2
 9         mov byte ptr ds:[3], 2
10         mov byte ptr ds:[4], 3
11         mov byte ptr ds:[5], 3
12         mov byte ptr ds:[6], 4
13         mov byte ptr ds:[7], 4
14      mov ah, 4ch
15         int 21h
16 code ends
17 end

使用masm、link工具汇编、链接的命令行及运行结果截图

汇编

链接

运行和运行结果

 

 

给出使用debug调试的截图

可执行文件加载后寄存器CX的值

使用u命令精确反汇编截图

查看PSP的命令及截图

使用g命令执行到line16退出执行之前

 

查看相应写入的内存单元

2. 实验任务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工具汇编、链接的命令行及运行结果截图

可执行文件加载后寄存器CX的值

使用u命令精确反汇编

灵活使用t命令/p命令、g命令,对ex2.exe进行调试的截图

可以看到在循环执行原汇编代码中 s: 到 loop 之间的指令。每次循环CX值自减,直到为0退出循环。

直接运行ex2.exe显示结果:

实验任务2小结:

ex1和ex2实现效果相同,都是向现存中写入相应数据,在屏幕上显示图形。只是ex1由程序员手动编写一条一条实现重复相同的指令,而ex2使用loop自动执行重复的数条指令。

3. 实验任务3

ex3源代码

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

存疑:为什么第一次给ax赋值数据需要加上0(0b800h而非b800h),否则汇编时会有severe error?

课本P104:在汇编程序中,数据不能以字母开头

ex3运行结果截图

0237H在虚拟机屏幕出现一排绿色数字7

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

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

 

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

由ex3结果推测数据中高位存放显示颜色,低位存放显示字符值。 

4. 实验任务4

源程序:

; ex4.asm
assume cs:code
code segment
        mov ax, 0000h
        mov ds, ax

        mov dx, 0200h
        mov cx, 0040h
        s: mov [dx], ax
        add dx, 0001h
        add ax, 0001h
        loop s
    
        mov ah, 4ch
        int 21h
code ends
end

注意这里地址偏移从0到3f,总共有64次循环,cx赋值为40h而非3fh。ex4实验内容时以字节(byte)为单位,向内存中存放数据,而寄存器ax长度为一个字,即两个字节。结果尝试这里程序使用al进行迭代自增得到的效果相同。

由于小端法存放低位数据存在内存地址低位,高位数据存在内存地址高位,且低位地址作为字的地址,因此使用长度为两个字节的寄存器为容器向内存存放字时,高位(本实验中为00)被存放到目标地址字节后面一个字节中,在下一次存放时,正好被低位数据覆盖,因此使用ax也能实现预计效果。 

汇编、链接无误:

 

使用debug的t命令、g命令、p命令调试:

略,直接一步-g命令执行完了。

用d命令查看0:200~0:23F,确认是否将0~63传送至此段内存区域:

 5. 实验任务5

课本填空后的代码:

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

查看复制目标地址,为了更加清晰,反汇编相应内存空间存放的指令

 程序思路:经过初次阅读可以看出,es(extra segment)用于存放目标位置段地址。ds是复制源的地址,程序开始段地址由cs给出,所以通过ax将cs值赋给ds。值得注意的是,inc指令没有特殊说明自增量为1,即这个程序逐字节复制内容,所以使用al存放1字节大小的数据。遇到困难的地方是s上方cx的填写,即循环次数的控制,起初尝试将ip的值赋给cx,但是ip不可被访问,汇编时报错。之后尝试了将程序长cx赋值给cx,出于不知道的原因,在复制完后汇编程序会陷入死循环。找到两种处理方式,一是基于反汇编看出需要复制的指令长度,人为赋值0015h给cx;第二种使用offset a,即a的偏移地址赋给cx。

6. 实验任务6

第一步:在vi编辑器中编写汇编程序

第二步:放弃

  

五、实验总结

1. 本次试验使用dosbox完成,使用masm等工具之前需要先把他们所在相应的路径作为磁盘mount到虚拟机上,即可使用edit编辑,masm汇编和link链接。

2. s:一行开始前给cx赋值是为了控制loop的次数,像实验4中需要目标地址偏移从0到3f,总共有64次循环,cx赋值为40h而非3fh。

3. 在汇编程序中,数据不能以字母开头,如果数据最高位是字母,需要在前面加上0。

posted @ 2020-10-31 19:31  RW_NEO  阅读(330)  评论(2)    收藏  举报