转移指令:可以修改IP,或者同时修改CS和IP的指令。
转移行为分类:
1.只修改IP,称为段内转移。如:jmp ax(IP=ax)
1.1 对IP的修改范围不同
IP的修改范围(-128,127),称为短转移。
IP的修改范围(-32768,32767),称为近转移。
2.同时修改CS和IP,称为段间转移。如:jmp 1000:0
转移指令分类:
1.无条件转移指令(如:jmp)
2.条件转移指令
3.循环指令(如:loop)
4.过程
5.中断
操作符0ffset
offset:取得标号的偏移地址
如:
mov ax,offset start (假定标号start的IP为1)
则其相当于mov ax,1
jmp指令
jmp为无条件转移指令,只修改IP(√),同时修改CS和IP(√)。
使用jmp指令要给出俩个信息:1.目的地址。2.转移的距离。
依据位移进行转移的jmp指令
jmp short 标号 (转到标号处执行指令)
这种格式的jmp指令实现的是段内短转移。对IP的修改范围为-128~127,也即从这个指令位置开始,向前转移最多128个字节,向后转移最多127个字节。“short”,指出是短转移;“标号”,指出要转移的目的地。IP改变,指令跳转至标号处。
1.mov ax,0
2.jmp short s
3.add ax,1
4.s:inc ax
1执行后,2开始执行,跳转至4。3执行嘛?不会,因为程序执行完4就向后面执行了。
在debug中,jmp short 标号,其对应的机器码都是 “EBab”,EB是固定的,ab可能是任意的俩位16进制数(这个因程序不同而不同),这个数字叫“八位位移”,那这个数字是怎么定义的?
八位位移 = 标号处的地址—jmp指令后的第一个字节的地址;
就拿上面的那个程序来说,八位位移=第4行的地址(标号处的地址)—第三行开始的地址(jmp指令后的第一个字节),其实也可以看作俩元素之间的其他指令所占据的内存大小。
所以,八位位移 = 俩元素之间的其他指令所占的内存大小
根据位移来进行指令的跳转,jmp short 标号的功能就是:IP=IP+八位位移。
jmp short 标号:段内短转移 由此,我们可以来介绍,jmp near ptr 标号:段内近转移
jmp near prt 标号 的功能为:IP=IP+16位位移。
所以它能跳转的范围就比段内短转移要大,范围为-32768~32767。其也是根据位移来进行跳转。
转移的目的地址在指令中的jmp指令
前面所讲的都是根据转移位移来进行的指令的跳转,现在我们来介绍依据转移的目的地址来进行的转移指令的方法。
"jmp far ptr 标号" 段间转移,又称为远转移。
简单的来说,就是取标号处的CS:IP来进行的指令跳转。
转移地址在寄存器中的jmp指令
'jmp 16 位寄存器" ,功能:(IP)=(16位寄存器)
转移地址在内存中的jmp指令
转移地址在内存中的jmp指令有俩种格式
1."jmp word ptr 内存单元地址" (段内转移)
2."jmp dword ptr 内存单元地址" (段间转移)
段内转移只是将IP修改为内存单元地址中存放的数据。
段间转移,因为dword是双字型(double word)数据,故其要涉及俩个16为寄存器,分别为CS和IP。这个功能是将内存单元地址中的值给到IP,内存单元地址+2中的值给到CS
jcxz指令
jcxz是条件转移指令,所有的条件转移指令都是短转移,转移都是依据位移的。前面说过,其转移的范围为-128~127。
操作:"jcxz 标号" (如果cx的值为0,则跳转至标号处,反之则不)
loop指令
loop指令是循环指令,所有的循环指令都是短转移,转移都是依据位移的。转移范围-128~127。
操作:"loop 标号" (cx=cx-1,如cx不等于0,转移到标号处执行,反之则不)
编译器对转移位移超界的检测
根据位移进行转移的指令,它们的转移范围受到转移位移的限制,如果出现了转移范围超界的问题,编译器将报错。
另外,jmp 2000:0100 的转移指令,是在debug中使用的汇编指令,汇编编译器并不认识,如果在源程序中使用,编译时会报错。