[BX]和loop指令
[BX]
[BX]和[0]有些类似[0]表示偏移地址为0段地址在DS寄存器中,而[BX]是偏移地址为BX寄存器中的内容,段地址也是在DS寄存器中。为了下文描述方便我们定义一个符号()表示一个寄存器或一个内存单元中的内容,比如(ax)表示寄存器ax中的内容。
inc 寄存器这条指令是让寄存器中的内容加1,比如 inc bx就是把bx寄存器中的内容+1。
LOOP指令
loop指令的格式是:loop 标号,cpu执行loop指令的时候,要进行两部操作:
- (cx) = (cx) -1
- 判断cx中的值,不为零则转至编号处执行程序,如果为零则向下执行。
我们需要注意的是cx寄存器中存放着循环次数。
用cx和loop指令相配合实现循环功能的框架如下:
mov cx,循环次数
s:
循环执行的程序段
loop s
可以总结以下三点规律
在cx中存放循环次数
loop指令中的标号所表示的地址要在前面
要循环执行的程序段,要写在标号和loop指令的中间。
在汇编源程序中还有一点需要特别注意:数据不能以字母开头,比如ffffh只能写成0fffffh。
通过debug模式跟踪循环的执行我们发现在debug模式下,循环标记变成一个地址,当判断是否满足cx不为0的条件后,如果满足就将ip寄存器中的值改变为循环标记代表的偏移地址值,从而完成跳转。
在debug模式时如果我们想直接跳到某条命令让其执行,可以直接使用 g 偏移地址来完成。比如 g 0012表示cs:0012之前的指令已经完成了。如果我们通过观察几次循环便认为逻辑是正确的,那么便可直接通过p命令直接一次性执行完循环指令。或者直接用 g 偏移地址的方法跳转到循环已经执行完成后的汇编指令。
特别注意 Debug和汇编编译器masm对指令的不同处理
我们在debug中写过类似的指令:
mov ax, [0]
这在debug中认为是将偏移地址为0的值送入ax中,而在masm编译器认为这是将值0送入ax寄存器中。
所以要想达到统一效果可以将值放入中转寄存器中,比如 先将0送入bx中,再用 mov ax,[bx]达到和debug模式 mov ax,[0]同一效果。这样做比较麻烦,我们还可以换一种做法,显示支出段地址和偏移地址来完成。比如 mov al,ds:[0]。
段前缀
形如mov ax,ss:[0]这些出现在访问内存单元的指令中,用于显示地指明内存单元的段地址的‘’ds:‘’在汇编语言中称为段前缀。
一段安全的空间
在8086模式中,随意向一段内存空间写入内容是很危险的,因为这段空间中可能存放着重要的系统数据或代码。一般DOS和其他合法的程序一般都不会使用0:200~0:2ff这段空间。