[BX]和对内存单元的描述
[0] 表示内存单元,它的偏移地址是0。 [BX] 同样表示一个内存单元,它的偏移地址是 (BX) 。
例如,“ MOV AX, [BX]
”指令会将 DS:BX
指向内存单元中的数据移到寄存器 AX 上。
INC指令和LOOP指令
INC
container
container
对应的寄存器或存储空间中的值增加1。这个指令比 ADD 指令的执行速度快,且占用空间小。
LOOP
label
LOOP
指令时,需要进行两步操作:
(CX)-=1
- 判断 CX 中的值,如果不为0则转至 label 对应的标号处执行程序,如果为0则向下继续执行
从上面描述中可以看到,CX 寄存器中的值影响着 LOOP 指令的执行结果。通常,使用 LOOP 指令来实现循环功能,CX 中存放循环次数。
标号在汇编指令中常常出现在某条语句前,以“ label ”的形式标识某一条语句,代表该地址处有这样一条指令。例如:
标号代表的地址在语句“ ADD AX, BX
”的地址处。
以下是一个利用指令和 CX 寄存器实现的乘方程序,用于计算210:
该程序一共经历了9次乘方,具体的循环过程分析如下:
- 第一次使用 MOV 指令初始化一个2
- 每次执行 ADD 指令都相当于进行一次平方运算
- CX 寄存器被初始化为9,LOOP 指令每次判断前都使 CX 减少1,只有
(CX)
不为0时才开始循环,这样的循环一共重复8次,再加上最开始进入循环前的一次 ADD 运算,一共进行9次平方运算,所以得到210。
从上面的过程中,可以总结出CX寄存器和LOOP指令配合实现循环的要点:
- 在 CX 中存放循环次数
- LOOP 指令中的标号所标识的地址要在循环开头处
- 要循环执行的程序段,应位于标号和 LOOP 指令的中间
用 CX 寄存器和 LOOP 指令配合实现循环功能的程序框架如下:
lopseg:
; loop codes
loop lopseg
段前缀
在汇编源程序中,如果需要用指令访问内存单元,需要在指令中使用“ […]
”来表示一个内存单元。如果在其中使用一个常量“ n
”直接给出内存单元的偏移地址,需要在方括号前面用段寄存器标签如“ DS:[0]
”显式给出段地址所在的段寄存器,否则部分编译器(如masm)会将其直接解释为常量“ n
”。
如果在方括号内使用寄存器 BX 间接给出内存单元的偏移地址,则段地址默认在 DS 中。可以在访问内存单元的指令中显式地给出内存单元所在的段寄存器,例如“ CS:
”、“ SS:
”,称为段前缀。
以下示例程序用来计算FFFF:0~FFFF:F内存单元中存储数据的和:
第一,FFFF:0~FFFF:F一共16个单元,每个单元存储的最大数据为255,因此结果 DX 可以存放下。
第二,DX 是16位寄存器,内存单元存放的是8位数据,不能直接相加,只能通过 AX 寄存器间接相加。
第三,使用 LOOP 指令和递增 BX 来遍历内存单元。