文章目录
前言
1. jcxz 指令
1.1 什么是jcxz指令
对IP的修改范围都为-128~127。
指令格式:jcxz 标号(如果(cx)=0,则转移到标号处执行。)
1.2 如何操作
"jcxz 标号"指令操作:
-
当(cx)=0时,(IP)=(IP)+8位位移;
-
8位位移=“标号”处的地址 - jcxz指令后的第一个字节的地址;
-
8位位移的范围为-128~127,用补码表示;
-
8位位移由编译程序在编译时算出。
-
当(cx)=0时,什么也不做(程序向下执行)。
2. loop 指令
2.1 什么是loop指令
对IP的修改范围都为-128~127。
指令格式:loop 标号((cx))=(cx)-1,如果(cx)≠0,转移到标号处执行。)
2.2 如何操作
"loop 标号"指令操作:
(1)(cx)=(cx)-1;
(2)如果(cx)≠0,(IP)=(IP)+8位位移。
-
8位位移=“标号”处的地址-loop指令后的第一个字节的地址;
-
8位位移的范围为-128~127,用补码表示;
-
8位位移由编译程序在编译时算出。
-
当(cx)=0,什么也不做(程序向下执行)。
3. 根据位移进行转移的意义
3.1 为什么?
前面我们讲到:
jmp short 标号
jmp near ptr 标号
jcxz 标号
loop 标号
等几种汇编指令,它们对 IP的修改是根据转移目的地址和转移起始地址之间的位移来进行的。
在它们对应的机器码中不包含转移的目的地址,而包含的是到目的地址的位移距离。
3.2 举例说明
例如:
这段程序装在内存中的不同位置都可正确执行,因为 loop s 在执行时只涉及到s的位移( - 4,前移 4个字节,补码表示为FCH),而不是s的地址。
如果loop s的机器码中包含的是s的地址,则就对程序段在内存中的偏移地址有了严格的限制;因为机器码中包含的是 s 的地址,如果 s 处的指令不在目的地址处,程序的执行就会出错。
而loop s的机器码中包含的是转移的位移,就不存在这个问题了;。
4. 编译器对转移位移超界的检测
注意,根据位移进行转移的指令,它们的转移范围受到转移位移的限制,如果在源程序中出现了转移范围超界的问题,在编译的时候,编译器将报错。
比如,下面的程序将引起编译错误:
assume cs:code
code segment
start: jmp short s
db 128 dup(0)
s: mov ax,0ffffh
code ends
end start
报错如下:
jmp shorts的转移范围是-128~127,IP最多向后移动127 个字节,
我们在前面的文章中讲到的形如“jmp 2000:0100
”的转移指令,是在 Debug 中使用的汇编指令,汇编编译器并不认识。如果在源程序中使用,编译时也会报错。
结语
今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。
也可以点点关注,避免以后找不到我哦!
Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!