资料来源:汇编语言第二版-王爽
1.loop指令
loop指令为循环指令,所有的循环指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。
对ip的修改范围都为:-128~127。
指令格式:loop 标号
( (cx) = (cx) - 1 ,如果(cx)≠0,转移到标号处执行。)
操作:(1) (cx)=(cx)-1;
(2) 如果(cx)≠0,(ip)=(ip)+8位位移。
如果(cx)=0,什么也不做(程序继续向下执行)。
我们从loop的功能可以看出,指令 'loop 标号' 的功能相当于:
(cx)--;
if((cx) ≠ 0) jmp short 标号;
2.根据位移进行转移的意义
jmp short 标号、jmp near ptr 标号、jcxz 标号、loop 标号等几种汇编指令,它们对ip的修改是根据转移目的地址和转移起始地址之间的位移来进行的。在它们对应的机器码中不包含转移的目的地址,而包含的是目的地址的位移。
这种设计,方便了程序段在内存中的浮动装配。
例如:
汇编指令 机器指令
mov cx,6 B9 06 00
mov ax,10 B8 10 00
s: add ax,ax 01 C0
loop s E2 FC
这段程序装在内存中的不同位置都可以正确执行,因为loop s 在执行时只涉及到s的位移(-4,前移4个字节,补码表示为FCH),而不是s的地址。如果loop s的机器码中包含的是s的地址,则就对程序段在内存中的偏移地址有了严格的限制,因为机器码中包含的是s的地址,如果s处的指令不在目的地址处,程序的执行就会出错。而loop s的机器码中包含的是转移的位移,就不存在变个问题了,因为,无论s处的指令的实际地址是多少,loop指令的转移位移是不变的。
3.编译器对转移位移超界的检测
根据位移进行转移的指令,它们的转移范围受到转移位移的限制,如果在源程序中出现了转移范围超界的问题,在编译的时候,编译器将会报错。
例如下面的程序将引起编译错误:
assume cs:code
code segment
start: jmp short s
db 128 dup (0)
s: mov ax, 0ffffh
code ends
end start
因为 jmp short s转移范围是-128~127,ip最多向后移动127个字节,而这个例子中s的转移位移是128,超出了转移范围,所以会引起编译错误。
有错误请指正,谢谢!