汇编语言[bx]和Loop指令

1、 [bx]和内存单元的描述

[bx]是什么呢?和[0]有些类似,[0]表示内存单元,它的偏移地址是0。比如在下面的指令中(在Debug中使用):

mov ax,[0]

将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个多,偏移地址为0,段地址在ds中。
bx为偏移地址,段地址默认为ds。因此,上面指令作用就是将ax中的数据送入内存ds:bx处,即:((ds)*16 + (bx)) = (ax)

mov ax,[bx]

也可以通过下面指令实现上面指令功能:

mov ax,ds:[bx]
//mov ax,es:[bx]

通过这种ds:[bx],通过这种方式来获得ds:bx中的内容。同理也可以获得es:[bx]中的内容。

mov al,[0]

将一个内存单元的内容送入al,这个内存单元的长度为1字节(字节单元),存放一个字节,偏移地址为0,段地址在ds中。
要完整地描述一个内存单元,需要两种信息:
①内存单元的地址;
②内存单元的长度(类型)。
用[0]表示一个内存单元时,0表示单元的偏移地址,段地址默认在ds中,单元的长度(类型)可以由具体指令中的其他操作对象(比如说寄存器)指出。
[bx]同样也表示一个内存单元,它的偏移地址在bx中,比如下面的指令:

mov ax,[bx]

将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址在bx中,段地址在ds中。

mov al,[bx]

将一个内存单元的内容送入al,这个内存单元的长度为I字节(字节单元),存放一个字节,偏移地址在bx中,段地址在ds中。

2、loop

英文单词“loop”有循环的含义,显然这个指令和循环有关。
我们在这一章,讲解[bx]和loop指令的应用、意义和相关的内容。

mov cx,12H
s:
   mov dx,es:[bx]
   mov ds:[bx],dx
   inc bx
loop s
mov ax,4c00H

功能:

通过loop,来完成循环操作。

下面对参数进行一一讲解:

s:标记符,标记符就是其所在的指令的地址。例如上面程序:s就表示mov dx,es:[bx]指令的地址。

cx:相当于for循环中的x,每次运行到loop指令时,cx的数值就会 -1 。当cx为零的时候,退出loop循环。

loop: 当cpu执行loop的时候,要进行两步操作:

(1)cx = cx - 1
(2)判断cx中的数值是否为0。不为0则转至标号s所标识的地址处执行(这里的指令是mov dx,es:[bx]),如果为0则执行下一条指令(下一条指令是mov ax,4c00H)

3.我们定义的描述性的符号:“()”

为了描述上的简洁,在以后的课程中,我们将使用一个描述性的符号“()”来表示一个寄存器或一个内存单元中的内容。比如:
(ax)表示ax中的内容、(al)表示al中的内容;
(20000H)表示内存20000H单元的内容(()中的内存单元的地址为物理地址);
((ds)* 16+(bx))表示:
ds中的内容为ADR 1, bx中的内容为ADR2,内存ADR1 X 16+ADR2单元的内容。
也可以理解为:ds中的ADR1作为段地址,bx中的ADR2作为偏移地址,内存ADRI :ADR2单元的内容。
注意,“()”中的元素可以有3种类型:
①寄存器名:
②段寄存器名;
③内存单元的物理地址(一个20位数据)。
比如:

(ax), (ds), (al), (cx), (20000H), ((ds)*16+(bx))等是正确的用法;
(2000:0), ((ds):1000H)等是不正确的用法。

我们看一下(X)的应用,比如,

(1)  ax中的内容为0010H,可以这样来描述:(ax)=0010H;
(2)  2000:1000处的内容为0010H,可以这样来描述:(21000H)=0010H ;
(3)  对于mov ax,[2]的功能,可以这样来描述:(ax)=((ds)* 16+2);
(4)  对于mov [2],ax的功能,可以这样来描述:((ds)* 16+2)=(ax);
(5)  对于add ax,2的功能,可以这样来描述:(ax)=(ax)+2;
(6)  对于add ax,bx的功能,可以这样来描述:(ax)=(ax)+(bx);
(7)  对一于push ax的功能,可以这样来描述:
    (sp)=(sp)-2
    ((ss)*16+(sp))=(ax)
(8) 对于pop ax的功能,可以这样来描述:
    (ax)=((ss)* 16+(sp))
    (sp)一(sp)+2

"(X)”所表示的数据有两种类型:
①字节:
②字。是哪种类型由寄存器名或具体的
运算决定,比如:
(al), (b1), (c1)等得到的数据为字节型;(ds), (ax), (bx)等得到的数据为字型。
(al)=(20000H),则(20000H)得到的数据为字节型;(ax)=(20000H),则(20000H)得到的数据为字型。

4.约定符号idata表示常量

我们在Debug中写过类似的指令:mov ax,[0],表示将ds:0处的数据送入ax令中,
指令中,在“[…]”里用一个常量0表示内存单元的偏移地址。以后,我们用idata表示常量。比如

mov ax,[idata]就代表mov ax,[ 1]、mov ax,[2]、mov ax,[3]等。
mov bx,idata就代表mov bx, l、mov bx,2, mov bx,3等。

mov ds,idata就代表mov、mov ds,2等它们都是非法指令。

loop 和 [bx]混合运用

assume cs:code
code segment
    mov ax,20H
    mov ds,ax
    mov bx,0
    mov cx,40H
s:
    mov [bx],bx
    inc bx
loop s
    mov ax,4c00H
    int 21H
code ends
end

上面代码,实现了向内存0:200~0:23F,依次传送数据0~63(3FH)的功能。


发布日期:

所属分类: 易语言 标签: