第五章 【BX】和loop指令
完整描述一个内存单元的条件:①内存单元的地址。②内存单元的长度。
用符号“()”来表示一个寄存器或一个内存单元中的内容。eg:(ax)、(al)。“()”中表示的数据有两种:①字节;②字。是哪种类型由寄存器名或具体的运算决定。
注意:①()中的元素可以有3中类型:①寄存器名;②段寄存器名;③内存单元的物理地址(一个20位数据)
引入:以后可用idata表示常量。eg:mov ax,[idata]可表示mov ax,[0]、mov ax,[1]、mov ax,[2]等。
一、[BX]
mov ax,[bx]与mov [bx],ax功能类似于mov ax,[0]和mov [0],ax.
inc bx作用是bx中内容加一。inc 内存单元。eg:inc byte ptr [3]-----ds:3 ← ((ds)×16 +3) + 1
二、Loop指令
格式:loop 标号。执行loop指令的两个步骤:
①(cx)=(cx)-1
②判断cx中的值,不为零则转至标号处执行程序,如果为零则向下执行。
(cx中放的一般是循环的次数。)
(eg:(loop指令的使用)
assume cs:code
code segment
mov ax,2
mov cx,11
s:add ax,ax
loop s
mov ax,4c00h
int 21h
code ends
end
其中标号s代表了一个地址,地址处的指令为:add ax,ax
执行时,实际是执行了两步(①和②)主要的和循环相关的指令是:
mov cx,11
s:add ax,ax
loop s)
三个要点:①在cx中存放循环的次数。
②loop指令中的标号所标识的地址要在前面。
③要循环执行的程序段,要写在标号和loop指令的中间。
实现循环功能的框架: mov cx,循环次数
s:循环执行的程序段
loop s
三、在Debug中跟踪用loop指令实现的循环程序
注意:在汇编源程序中,数据不能以字母开头,所以要在前面加0。
eg:mov AX,0ffffh
小结:
t命令:单步执行;遇loop会进入循环内部继续单步执行; 遇int会进入中断程序内继续单步执行。
p命令:单步执行;遇loop或int会当做整体执行,不进入内部单步执行。(上一章实验内用p命令执行int 21 的原因。)
g命令:执行到指定地址;或遇程序结束或int,则终止执行。
四、Debug和汇编编译器masm对指令的不同处理
①对于指令中的[idata]
Debug将它解释为内存单元,idata是偏移地址,而编译器将它解释为idata(实数)。
解决方法:①在编译器中,要在“[ ]”的前面加上段地址所在的段寄存器。eg:mov al,ds:[0]
②在“[ ]”里用的是寄存器,eg:bx。则段地址默认在ds中。也可以像①中给出段地址所在的段寄存器。
五、loop和[bx]的联合应用(略)
六、段前缀:用于显示地指明内存单元的段地址的“ds:”、“cs:”、“ss:”、“es:”,在汇编语言中称为段前缀。
七、安全空间
概念引出原因:防止改变空间内原本存放的重要的系统数据或代码,产生错误。
总结:
需要直接向一段内存写入内容时,这段内存空间不应该存放系统或其他的程序的数据或者代码,否则很可能引发错误。在DOS方式下,一般情况下,0:200~0:2ff空间中没有系统和其他程序的代码和数据。以后,需要时可以使用。
八、段前缀的使用(略去,应用详见实验4)