汇编语言实验二
汇编语言实验二
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之前),观察结果。
实验内容:
通过实验我们可以观察到,在使用masm命令之后文件夹中会多出一个ex1.obj的文件,这就是得到的目标文件,要想使其变为可执行文件,还需使用link进行连接。
执行结果:
使用d命令查看psp的前256个字节“
精确反汇编:
使用g查看第16行:
实验任务二
使用任意一款文本编辑器,编写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,它们实现的是否是相同的功能和效果?在具体实现上有什么不同?
执行结果:
t命令调试:
p命令调试:
g命令调试:直接跳到代码结束处:
将 mov cx, 4改为8:
通过对ex2.asm和ex1.asm对比我们可以发现,两个文件的作用都是向显存中写入数据,第一个是使用mov byte ptr 段地址:偏移地址的方法来向显存中写入数据,因为每次写进去一个byte的数据,因此4个图像总共要写8次;但是ex2.asm使用循环,每一次将ax寄存器中的数据写入缓存之中,由于ax寄存器是16位的因此只需循环4次就可以完成相同的任务;
实验任务3
综合使用loop,[bx],编写完整汇编程序,实现向内存b800:07b8开始的连续16个字单元重复填充字数据0237H。
要求:
- 编写汇编源程序
- 给出运行结果截图
如程序编写正确,预期结果如图所示。(运行前先使用 命令清屏,更便于观察运行结果)
- 把填充的字数据,从0237H 改成0239H,再次保存后,汇编、链接、运行,观察结果。把填充的字数据,从0237H 改成0437H,再次保存后,汇编、链接、运行,观察结果。猜测并分析,这个字数据中高位字节里存放的是什么信息,低位字节里存放的是什么信息。
程序代码如下:
;ex3.asm
assume cs:code
code segment
mov ax,0b800h
mov ds,ax
mov bx,07b8h
mov cx,16
s: mov dx,0237h
mov ds:[bx],dx
add bx,2
loop s
mov ax,4ch
int 21h
code ends
end
运行结果如下:
进行两次改动:
通过比较改动的代码和运行的结果我们可以很容易的发现,mov dx 0237h,诸如此类的代码,高两位代表的是颜色,而低两位则代表的是数字的字符。
实验任务4
- 编写完整汇编源程序,实现向内存0:2000:23F依次传送数据063(3FH)。
- 必做
- 综合使用[bx]和loop,编写汇编源程序灵活使用debug的t命令、g命令、p命令调试。在程序退出前,用d命令查看 0:2000:23F,确认是否将03F传送至此段内存区域。
- 选做*
- 利用栈的特性,综合使用loop,push实现(限定仅使用8086中已学过指令实现),编写源程序
- 灵活使用debug的t命令、g命令、p命令调试。在程序退出前,用d命令查看 0:2000:23F,确认是否将03F传送至此段内存区域。
- 必做
程序代码如下:
(书上的题目要求只用9步,这里尽最大的可能去省略不必要的步骤)
;ex2.asm
assume cs:code
code segment
mov bx,020h
mov ds,bx
mov bx,0
mov cx,64
s: mov[bx],bx
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end
t命令调试:
p命令调试:
g命令跳转:
d命令查看:
选做内容:
使用栈来完成传输:
assume cs:code
code segment
mov ax,0000h;
mov ss,ax
mov sp,0240h
mov cx,32
mov ax,3f3eh
s: push ax
sub ax,0202h
loop s
mov ax,4c00h
int 21h
code ends
end
因为可以将栈是倒序的,因此将想要输入的区域设为栈区,栈顶应该放的就是3e3fh,然后依次类推,每push一次就将push的寄存器减去0202h;
效果:
实验任务5
教材实验4(3)(P121)
Tips: 这道练习,本质仍然是复制,只不过复制的是自身代码。填空的关键是,如何确定复制多少字节。
补全代码如下:
;ex2.asm
assume cs:code
code segment
mov ax,cs
mov ds,ax
mov ax,0020h
mov es,ax
mov bx,0
sub cx,5
s:mov al,[bx]
mov es:[bx],al
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end
因为要求吧mov ax,4c00h之前的代码存储,其中mov ax,4cooh int 21h总共占了5个字,因此程序的长度cx应该减去5,所以第二空使用使用sub cx,5 ;cs寄存器保存中程序的起始地址,因此需要使用ax将cs赋值给ds寄存器。
执行的最终结果:
实验结论
- 本次实验是我熟悉了asm文件的编译链接操作的原理和过程。
- 熟悉了debug的底层原理,能够熟练的使用t、p、g命令根据不同的情况进行不同的调试。
- 进一步理解了loop循环的操作过程,以及应用情况,能够利用循环来解决基本的复制粘贴内存数据的简单问题。
- 对编译器debug功能的底层有了更深一步的了解。