文章目录
[BX]和loop指令
1 [bx]
我们用[bx]表示一个内存单元,它的段地址默认在ds中,它的偏移地址在bx中,比如下面的指令:
mov ax,[bx]
mov al,[bx]
2 Loop指令
loop指令用于循环操作
指令的格式是:loop 标号
CPU 执行loop指令的时候,要进行两步操作:
① (cx)=(cx)-1;
② 判断cx中的值,不为零则转至标号处执行程序,如果为零则向下执行。
用loop指令计算212:
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
3 在Debug中跟踪用loop指令实现的循环程序
计算ffff:0006单元中的数乘以3,结果存储在dx中。
代码如下:
assume cs:abc
abc segment
mov ax,0ffffh
mov ds,ax
mov bx,6
mov al,[bx]
mov dx,0
mov cx,3
s: add dx,ax
loop s
mov ax,4c00h
int 21h
abc ends
end
在汇编源程序中,数据不能以字母开头,所以要在第四行的ffff前面加0。
可以用p
命令直接完成循环。
4 Debug和汇编编译器Masm对指令的不同处理
我们在Debug中写过类似的指令:
mov ax,[0]
表示将ds:0处的数据送入al中。
但是在汇编元程序中,指令“mov ax,[0]”被编译器当作指令“mov ax,0”处理,即编译器无法将[0]识别成一个内存地址,而是会将其当成数字。
这个问题有两种解决方案:
-
通过BX来代替[0],我们先mov bx, 2 再通过mov ax, [bx]来完成。
-
在偏移地址前加上段地址,即mov al, ds:[0]。
5 loop和[bx]的联合应用
计算ffff:0~ffff:b单元中的数据的和,结果存储在dx中。
代码如下:
assume cs:abc
abc segment
mov ax,0ffffh
mov ds,ax
mov bx,0
mov dx,0
mov cx,12
s: mov al,[bx]
add dx,ax
inc bx
loop s
mov a,4cooh
int 21h
abc ends
end
这时我们就不用能常量给出内存单元的地址,而是用bx作为内存单元地址的变量。
6 段前缀
这些出现在访问内存单元的指令中,用于显式地指明内存单元的段地址的“ds:”、“cs:”、“ss:”或“es:”,在汇编语言中称为段前缀。
7 一段安全的空间
在8086模式中,随意向一段内存空间写入内容是很危险的 ,因为这段空间中可能存放着重要的系统数据或代码。
在一般的PC机中,DOS方式下,DOS和其他合法的程序一般都不会使用0:200~0:2FF( 0:200h~0:2FFh)的256 个字节的空间。所以,我们使用这段空间是安全的。
以后,我们需要直接向一段内存中写入内容时,就使用0:200~0:2FF这段空间。
8 段前缀的使用
将内存ffff:0~ffff:b段元中的数据拷贝到 0:200~0:20b单元中。
代码一:
assume cs:abc
abc segment
mov bx,0
mov cx,12
s: mov ax,0ffffh
mov ds,ax
mov dl,[bx]
mov ax,0020h
mov ds,ax
mov [bx],dl
inc bx
loop s
mov a,4cooh
int 21h
abc ends
end
因源单元ffff:X和目标单元0020:X 相距大于64KB,在不同的64KB段里,程序中,每次循环要设置两次ds。
这样做是正确的,但是效率不高。
我们可以使用两个段寄存器分别存放源单元ffff:X和目标单元0020:X的段地址,这样就可以省略循环中需要重复做12次的设置ds的程序段。
代码二:
assume cs:abc
abc segment
mov ax,0ffffh
mov ds,ax
mov ax,0020h
mov es,ax
mov bx,0
mov cx,12
s: mov al,[bx]
mov es:[bx],al
inc bx
loop s
mov a,4cooh
int 21h
abc ends
end
标签:abc,BX,mov,指令,ax,bx,loop
From: https://blog.csdn.net/weixin_74144099/article/details/136856662