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)的功能。