loop 指令为循环指令,所有的循环指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对 IP 的修改范围都为:-128~127。
指令格式:loop 标号
操作:
- (cx)=(cx)-1
- 如果 (cx)≠0,(IP)=(IP)+8 位位移。
8 位位移=标号处的地址-loop指令后的第一个字节的地址
8 位位移的范围为-128~127,用补码表示
8 位位移由编译程序在编译时算出。
如果 (cx)=0,什么也不做(程序继续向下执行)。
使用 C 语言描述的话:
cx--;
if ((cx) !=0 ) jmp short 标号;
有此可见,如果 cx 是 5
,其实 jmp
只有 4
次
检测点 9.3
补全编程,利用 loop 指令,实现在内存 2000H 段中查找第一个值为 0 的字节,找到后将它的偏移地址放到 dx 中
assume cs:code
code segment
start: mov ax, 2000h
mov ds, ax
mov bx, 0
s: mov cl, [bx]
mov ch, 0
___________
inc bx
loop s
ok: dec bx
mov dx, bx
mov ax, 4c00h
int 21h
code ends
end start
分析:
mov cl, [bx]
mov ch, 0
到这里,其实是将 [bx]
所指向的内存单元的一个字节的内容放置到 cx
寄存器中
然后要看 loop 指令执行的步骤 - 先要将 cx 减 1,然后判断 cx 中的值是否为 0,
如果不是 0 就继续循环,所以要想判断内存中的字节是否为零,需要补全的内容就是先让
cx 加1,故答案如下
assume cs:code
code segment
start: mov ax, 200h
mov ds, ax
mov bx, 0
s: mov cl, [bx]
mov ch, 0
inc cx
inc bx
loop s
ok: dec bx
mov dx, bx
mov ax, 4c00h
int 21h
code ends
end start