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

  • 2020 年 11 月 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的用途
三、实验内容
 
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之前),观察结果。

 debug调试:

 • d命令查看程序段前缀PSP所占的256个字节。

  • u命令反汇编

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

dubug调试:

 单步调试循环指令loop:

 

 

 单步调试中断指令int:

loopint时直接用P命令:

 经观察发现,t命令单步执行,每次只执行一条代码语句,遇到子程序后进入子程序逐条执行指令。p命令,类似t命令。若有子程序,直接执行完子程序全部指令而不是逐条执行指令,在遇到循环指令loop时,会直接执行志cx递减至0。

ex2.asm中line9为mov cx, 4时:

改成 mov cx, 8 ,保存后重新汇编、链接、运行:

ex2.asm和ex1.asm,它们实现的是否是相同的功能和效果?在具体实现上有什么不同

通过上述实验可知,他们实现的功能和效果相同,都完成了图案的输出。

具体实现上,ex1.asm使用了byte ptr的形式直接填入了8个数,而ex2.asm使用了loop循环将值存入显存。

 

3. 实验任务3
综合使用loop,[bx],编写完整汇编程序,实现向内存b800:07b8开始的连续16个字单元重复填充字数据0237H。
要求:
  • 编写汇编源程序、给出运行结果截图。
  • 把填充的字数据,从0237H 改成0239H,再次保存后,汇编、链接、运行,观察结果。
  • 把填充的字数据,从0237H 改成0437H,再次保存后,汇编、链接、运行,观察结果。
猜测并分析,这个字数据中高位字节里存放的是什么信息,低位字节里存放的是什么信息。

 (1)填充数据0237H

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

    mov bx,07b8h
    mov ax,0237H
    mov cx,10h
s:    mov [bx],ax
    add bx,2
    loop s
    mov ah,4ch
    int 21h
code ends
end

(2)填充数据0239H

 

 (3)填充数据0437H

 

 观察后猜想:高位字节存放的是颜色信息,低位字节是内容信息。

 

4. 实验任务4
编写完整汇编源程序,实现向内存0:200~0:23F依次传送数据0~63(3FH)。
♦ 必做
  • 综合使用[bx]和loop,编写汇编源程序
  • 灵活使用debug的t命令、g命令、p命令调试。在程序退出前,用d命令查看0:200~0:23F,确认是否将0~3F传送至此段内存区域。
♦ 选做*
  • 利用栈的特性,综合使用loop,push实现(限定仅使用8086中已学过指令实现),编写源程序
  • 灵活使用debug的t命令、g命令、p命令调试。在程序退出前,用d命令查看0:200~0:23F,确认是否将0~3F传送至此段内存区域。
♦ Tips:
这道练习,本质上就是把一组连续的字节数据(常数),送到指定的连续的字节单元。
如果利用栈实现,借助push和loop实现连续入栈操作。需要注意:
① 初始时ss和sp的设置
② 8086的入栈操作,是从高地址单元→低地址单元方向的;
③ 8086的入栈操作,只能以字为单元。但这里是字节数据,如何灵活处理?

必做:

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

调试并用d命令查看数据是否存入此段内存区域:

 

 选做:

8086的入栈操作是从高地址向低地址,所以设置栈的段地址ss为0h,设置sp为0240h。又因8086入栈操作只能以字为单元。所以ax初始为3F3Eh,小端法栈里添加。

;ex44.asm
assume cs:code
code segment
    mov ax,0h
    mov ss,ax
    mov ax,0240h
    mov sp,ax
    mov ax,3F3Eh
    mov cx,20h
s:    push ax
    add ax,-0202h
    loop s
    mov ah,4ch
    int 21h
code ends
end
    
    
    

调试并用d命令查看数据是否存入此段内存区域:

 

5. 实验任务5
教材实验4(3)(P121)
♦ Tips:
这道练习,本质仍然是复制,只不过复制的是自身代码。填空的关键是,如何确定复制多少字节

 在确定复制多少字节时,可以先随意补全,用u命令精准反汇编,找到mov  ax, 4c00h。来确定要复制的字节数。

 

 反汇编后可知 mov ax,4c00 命令位于0018h。所以要复制0-0017h所有字节,因此将0017复制给cx。由寄存器cs知要复制的代码位于076A段,所以将076A赋值给AX。

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

运行结果:

 

 汇编语言调试完毕后,反汇编查看内存单元 0:200-0:217处。发现复制成功。