汇编语言——转移指令(offset,jmp,jcxz)
操作符offset
操作符offset在汇编语言中是由编译器处理的符号,它的功能是取得标号的偏移地址([bx,bp,si,di])。
示例:使该程序在运行中将s处的一条指令复制到s0处。
1 assume cs:codesg 2 codesg segment 3 s: mov ax,bx ;(mov ax,bx 的机器码占两个字节) 4 mov si,offset s 5 mov di,offset s0 6 mov ax,cs:[si] 7 mov cs:[di],ax 8 s0: nop ;(nop的机器码占一个字节) 9 nop 10 codesg ends 11 ends
jmp指令
jmp为无条件转移,可以只修改IP,也可以同时修改CS和IP;
jmp指令要给出两种信息:
- 转移的目的地址
- 转移的距离(段间转移、段内短转移,段内近转移)
1、段内短转移
格式:jmp short 标号(转到标号处执行指令)
这种格式的 jmp 指令实现的是段内短转移,它对IP的修改范围为 -128~127,也就是说,它向前转移时可以最多越过128个字节,向后转移可以最多越过127个字节。
执行 jmp short 标号 指令的过程:
(1)从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲区;
(2)(IP) = (IP)+所读取指令的长度(8位地址,因为范围是-128~127),从而指向下一条指令;
(3)执行指令。转到1,重复这个过程。
所以 CPU在执行 jmp short 标号 指令时并不需要转移的目的地址,只需要知道转移的位移就行了。
2、段内近转移
格式:jmp near ptr 标号
指令“jmp near ptr 标号”的功能为:(IP)=(IP)+16位位移(一个段最大有2^16B)。
3、段间转移
格式:jmp far ptr 标号
(CS)=标号所在段的段地址;
(IP)=标号所在段中的偏移地址。
far ptr指明了指令用标号的段地址和偏移地址修改CS和IP。
转移地址在内存中的jmp指令
转移地址在内存中的jmp指令有两种格式:
(1) jmp word ptr 内存单元地址(段内转移)
功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址。内存单元地址可用寻址方式的任一格式给出。
(2) jmp dword ptr 内存单元地址(段间转移)
jcxz指令
jcxz指令为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为-128~127。
指令格式:jcxz 标号(如果(cx)=0,则转移到标号处执行。)
jcxz 标号 指令操作:
1、当(cx)=0时,(IP)=(IP)+8位位移)
- 8位位移=“标号”处的地址-jcxz指令后的第一个字节的地址;
- 8位位移的范围为-128~127,用补码表示;
- 8位位移由编译程序在编译时算出。
2、当(cx)!=0时,什么也不做(程序向下执行)。
loop指令
loop指令为循环指令,所有的循环指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为-128~127。
指令格式:loop 标号
((cx))=(cx)-1,如果(cx)≠0,转移到标号处执行。
loop 标号 指令操作:
(1)(cx)=(cx)-1;
(2)如果(cx)≠0,(IP)=(IP)+8位位移。
- 8位位移=“标号”处的地址-loop指令后的第一个字节的地址;
- 8位位移的范围为-128~127,用补码表示;
- 8位位移由编译程序在编译时算出。
当(cx)=0,什么也不做(程序向下执行)。