1、[BX]和[0]一样,也表示一个内存单元,他的偏移地址在bx中。
2、loop指令的格式是:loop标号,CPU执行loop指令的时候,要进行两步操作:
cx=cx-1;
判断cx的值。
不为0则转至标号处执行程序,如果为0向下执行。
通常我们用loop指令来实现循环功能,cx至关重要,它存放循环次数。
下面举一个具体的例子来解释下loop的用法:
assume cs:fallrain
fallrain segment
mov ax,2
mov cx,11
s: add ax,ax
loop s
mov ax,4c00h
int 21h
fallrain ends
end
在以上程序中:
s为标号,它实际上标识了一个地址,这个地址有一条指令:add ax,ax。
loop s则有两步操作:
cx = cx-1
判断cx中的值,不为0则转至符号s所标识的地址处执行(这里为add ax,ax),如果为0则执行下一跳指令(下一条指令是mov ax,4c00h)。
3、在汇编源程序中,数据不能以字母开头,所以要在前面加0,比如1234h在汇编中可以写成1234h,而fa11h在汇编中要写成0fa11h
4、分析这样一个问题:
计算0000:0~0000:b单元中的数据和,结果存储在dx中:
-
运算后的结果是否会超过dx所能存储的范围
0000:00000:b内存答案元中的数据是字节型的数据,范围在0255之间,12个这样的数据相加,结果不会大于65535,可以在dx中存放下。 -
我们能否将0000:0~0000:b中的数据直接累加到dx中?
不能,因为0000:0~0000:b中的数据是8位的,不能直接加到16位寄存器dx中。 -
我们能否将0000:0~0000:b中的数据累加到dl中,并设置(dh)=0,从而实现累加到dx中?
不能,因为dl是8位寄存器,能容纳的数据范围在0255之间,0000:00000:b中的数据也都是8位,如果仅向dl中累加12个8位数据,很可能造成进位丢失。 -
我们到底怎样将0000:0~0000:b中的8位数据,累加到16位寄存器dx中?
第一种方法中的问题是两个运算对象的类型不匹配,第二种方法中的问题是结果有可能超界。
目前我们可以:用一个16位的寄存器做中介。将内存单元中的8位数据赋值到一个16位寄存器ax中,再将ax中的数据加到ax上,从而使两个运算对象的类型匹配并且结果不会超界。
汇编代码如下:
assume cs:fallrain
code segment
mov ax,0000h
mov ds,ax
mov bx,0 //初始化ds:bx指向0000:0
mov dx,0 //初始化累加寄存器dx,(dx=0)
mov,cx,12 //初始化循环计数寄存器cx,(cx)=12
s: mov al,[bx]
mov ah,0
add dx,ax
inc bx
loop s
mov ax,4c00h
int 21h
fallrain ends
end
5、段前缀
指令mov ax,[bx]中,内存单元的偏移地址由bx给出,而段地址默认在ds中,我们可以在访问内存单元的指令中显式的给出内存单元的段地址所在的段寄存器,比如:
mov ax,ds:[bx]
mov ax,cs:[bx]
mov ax,ss:[bx]
mov ax,es:[bx]
mov ax,ss:[0]
mov ax,cs:[0]
像这些用于显式的知名内存单元的段地址的ss: cs: ds: es:,在汇编语言中称为段前缀。
6、一段安全的空间
在8086模式中,随意向一段内存空间写入内容是很危险的,因为这段空间中可能存放着重要的系统参数或代码。
我们似乎面临一种选择,是在操作系统中安全、规矩的编程,还是自由,直接的用汇编语言去操作真实的硬件,了解哪些早已被层层系统软件掩盖的真相?在大部分的情况下,我们选择后者,除非我们就是在学习操作系统本身的内容。
我们需要直接向内存中写入内容,可有不希望重要代码被覆盖,所以要找到一段安全的空间供我们使用,在一般的PC机中,DOS方式下,DOS和其他合法程序一般都不会使用0:2000:2ff(00200h002ffh)的256个字节的空间。所以我们使用这段空间是安全的.
以后,我们需要直接向一段内存中写入内容时,就是用0:200~0:2ff这段空间。