汇编语言_第9章 转移指令的原理

可以修改IP,或同时修改CS和IP的指令统称为转移指令。 转移指令就是可以控制CPU执行内存中某段代码的指令。
8086CPU的转移行为有以下几类:

  • 只修改IP时,称为段内转移,如:jmp ax

  • 同时修改CS和IP时,称为段间转移,如:jmp 1000:0
    由于转移指令对IP的修改范围不同,段内转移又分为 短转移和近转移。

    • 短转移IP 的修改范围为-128~127.
    • 近转移IP 的修改范围为-32768~32767.

8086CPU的转移指令分为以下几类:

  • 无条件转移指令。(如:jmp)
  • 条件转移指令
  • 循环指令(如:loop)
  • 过程
  • 中断

9.1 操作符offset

offset:取得标号的偏移地址。(在汇编语言中有编译器处理的符号)
在这里插入图片描述
在这里插入图片描述

9.2 jmp指令
jmp 为无条件转移指令,可以只修改IP,也可以同时修改CS和IP。
jmp指令给出2中信息:
(1)转移的目的地址
(2)转移的距离(段间转移、段内短转移、段内近转移)

9.3 依据位移进行转移的jmp指令
jmp short 标号(转到标号处执行指令)

  • IP修改范围:-128~127 ,即向前转移时可以最多越过128个字节,向后转移可以最多越过127个字节。
  • short:说明指令进行的是短转移。
  • 标号:代码段中的标号,指明了指令要转移的目的地,转移指令执行后,CS:IP应该指向标好处的指令。
    在这里插入图片描述
    jmp short标号的功能:(IP)=(IP) + 8位位移
    (1) 8位位移=标号处的地址 - jmp指令后的第一个字节的地址;
    (2) short指明此处的位移为8位位移;
    (3) 8位位移的范围为-128~127,用补码表示;
    (4) 8位位移由编译器程序在编译时算出。

在这里插入图片描述

9.4 转移的目的地址在指令中的jmp指令

jmp far ptr 标号 :实现的是段间转移,又称远转移。
功能如下:
(CS)=标号所在段的段地址;(IP)=标号在段中的偏移地址。
far ptr 指明了指令用标号的段地址和偏移地址修改CS和IP。

9.5 转移地址在寄存器中的jmp指令
指令格式:jmp 16位reg
功能:(IP)=(16位reg)

9.6 转移地址在内存中的jmp指令
转移地址在内存中的jmp指令有2中格式:
(1)jmp word ptr 内存单元地址(段内转移)
功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址。
在这里插入图片描述

(2)jmp dword ptr 内存单元偏移地址(段间转移)
功能:从内存单元地址处开始存放着2个字,高地址处的字是转移的目的段地址,低地址处是转移的偏移地址。
(CS)=(内存单元地址+2)
(IP)=(内存单元地址)
在这里插入图片描述

9.7 jcxz指令
jcxz 指令为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为:-128~127.
指令格式: jcxz 标号(如果(cx)=0,转移到标号处执行)
操作:当(cx)=0时,(IP)=(IP)+8位位移;
8位位移=标号处的地址—jcxz指令后的第一个字节地址;
8位位移范围为-128~127,用补码表示;
8位位移由编译程序在编译时算出。

当(cx)≠0时,什么也不做(程序向下执行)
“jcxz 标号”的功能相当于: if((cx)==0) jmp short 标号;

9.8 loop 指令
loop指令为循环指令,所有的循环指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。对IP的修改范围都为:-128~127.
指令格式:loop 标号((cx)=(cx)-1,如果(cx)≠0,转移到标号处执行)
操作:
(1)(cx)=(cx)-1;
(2)如果(cx)≠0,(IP)=(IP)+8位位移。
8位位移=标号处的地址—loop指令后的第一个字节地址;
8位位移范围为-128~127,用补码表示;
8位位移由编译程序在编译时算出。

如果(cx)=0,什么也不做(程序向下执行)
“loop 标号”的功能相当于:
(cx)–;
if((cx)≠0) jmp short 标号;

9.9 根据位移进行转移的意义
在这里插入图片描述
在这里插入图片描述

9.10 编译器对转移位移超界的检测
注意:根据位移进行转移的指令,它们的转移范围受到转移位移的限制,如果在源程序中出现了转移范围超界的问题,在编译的时候,编译器将报错。
在这里插入图片描述
注意:jmp 2000:0100 的转移命令,是在Debug中使用的汇编指令,汇编编译器并不认识。如果在源程序中使用,编译时也会报错。

附注2:
补码
补码思想:先确定用00000000b~01111111b表示0 ~ 127,然后再用它们按位取反+1后的数据表示负数。
如:00000000b:0 11111111b+1=00000000b:0
00000001b:1 11111110b+1=11111111b:-1
01111111b:127 10000000b+1=10000001b:-127

(1)最高位为1,表示负数;
(2)正数的补码取反+1 后,为其对应的负数的补码;负数的补码取反+1后,为其绝对值。

如:
1的补码:00000001b,取反+1:11111111b,表示-1.
-1的补码:11111111b,取反+1:00000001b,其绝对值为1.

To be continue…

猜你喜欢

转载自blog.csdn.net/madao1234/article/details/83983876