汇编——实验4

这次实验在实验3的基础上有增加一些新知识,主要是关于[bx]和loop的用法。

一、实验内容

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

assume cs:code
code segment
    mov ax,0b800h
    mov ds,ax
    mov bx,07b8h
    mov cx,16

  s:mov [bx],0441h
    add bx,2
    loop s

    mov ax,4c00h
    int 21h
code ends
end    

结果如图:屏幕中央出现16颗红色的爱心

将源代码程序中字数据0403h修改为0441h,再次运行,结果如下:16颗红色的爱心变为红色大写字母A

2.综合使用 loop,[bx],编写完整汇编源程序,实现向内存 0:200~0:23F 依次传送数据 0~63(3FH)。

(1)综合使用loop,[bx],mov实现

assume cs:code
code segment
    mov ax,0
    mov ds,ax
    mov bx,200h
    mov cx,64

  s:mov [bx],al
    inc bx
    inc al
    loop s

    mov ax,4c00h
    int 21h
code ends
end

使用debug调试情况如下:

(先使用g命令调试到loop s之前,接着调用p命令调试loop循环,最后分别用t、p命令调试mov ax,4c00h和int 21h。)

调用d命令查看内存单元地址为0:200-0:23f中的内容是否变为0~63,结果如图,0~63已传送到此段内存区域。

(2)利用栈的特性,综合使用 loop,push 实现(限定仅使用 8086 中已学过 指令实现)

assume cs:code
code segment
    mov ax,0
    mov ss,ax
    mov sp,240h
    mov cx,64
    mov ah,3fh
    mov bh,3eh
    mov al,bh

  s:push ax
    sub ah,2
    sub bh,2
    mov al,bh
    loop s

    mov ax,4c00h
    int 21h
code ends
end

在利用栈实现时,有几个需要注意的地方,(1)起初栈顶是指向0:240h的内存地址处,等到开始入栈时,SP=SP+2,SP=23eh,再入栈,SP再减2,就这样由高地址单元->低地址单元方向。

(2)入栈操作是以字为单位的,这意味着压入栈的每一个字的关系是高字节比低字节大1的。这里我借助了bh这个寄存器,将ah和bh寄存器分别从3fh和3eh处开始每次减2的循环,之后将bh的值送入al中。

使用debug调试情况如下:

由图可见,0~63一次传送至0:200h-0:23fh内存区域。

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

assume cs:code
code segment
    mov ax, cs   
    mov ds,ax
    mov ax,0020h
    mov es,ax
    mov bx,0
    mov cx,_17h___;或者写十进制数23
s:mov al,[bx] mov es:[bx],al inc bx loop s mov ax,4c00h int 21h code ends end

(1)第一空,将CS的值送入AX中,是因为这段程序就是从CS中的值指向的段地址开始的。根据题意,是要将一开始CS:IP所指向的内存地址mov ax,4c00h前CS:IP所指向的内存地址 中的值复制到从内存地址为0:200处开始的内存单元处。故而此时ds=cs。

(2)第二空,即判断要循环多少次,需判断在mov ax,4c00h之前有多少条指令,而cx中的值为整个程序的长度,只要将总长度减去mov ax,4c00h和int 21h的长度即可。在这里我先让cx=1,查看程序总共的长度。

由图可知,CX=001CH,mov ax,4c00h和int 21h这两条指令所占字节为5,则在mov ax,4c00h之前所有指令所占字节数为(CX)-5即为17H即23。

下面是调试结果:已将mov ax, 4c00h之前的指令复制到指定内存处

 二、总结与体会

1.在实验3和4中都涉及到了段地址为b800h的显存单元,在用汇编源程序写代码时,刚开始直接写成mov ax,b800h,在编译时报错,查找资料后发现常数在做第二操作数时,若最高位是十六进制的a~f,则前面要加0。(然后想起来老师在讲第三章时讲过这个问题...而我忘掉了)

2.在利用loop操作做循环时,循环次数需要确定,CX的值得还是蛮重要的,而我在写源程序时,对于循环次数有时不能很快确定,需要思考好一会儿...

3.实验4中实现了将字数据送到指定连续的字单元中,一组连续的字节数据送到指定的连续的字节单元等相关操作。在进行字数据的传送时需要注意偏移地址不再是每次循环加1,而是加2了。

原文地址:https://www.cnblogs.com/zjybel/p/9975841.html