目录
可以修改IP或同时修改CS和IP的指令统称为转移指令。
只修改ip时成为段内转移,同时修改ip和cs时称为段间转移
段内转移又分为短转移和近转移
短转移的范围是:-128~127
近转移ip修改的范围是-32768~32767
8086CPU的转移指令分以下几类:
无条件转移指令(jmp)
条件转移指令
循环转移指令(loop)
循环指令
过程
中断
这些转移指令的条件可能不同但是基本原理相同本章通过无条件转移指令jmp来理解CPU执行转移指令的基本原理
9.1操作符offset
由编译器处理的符号 :取得标号的偏移地址
mov ax,offset start
问题9.1
将指令复制到另一个位置实际上就是将对应的数据(机器码复制过去)
s: mov ax,bx
mov si,offset s ;得到s的偏移地址给si
mov di,offset s0 ;得到s0的偏移地址给di
mov dx,cs:[si] ;将cs:[si]中的数据(也就是s对应的机器码)给到寄存器dx中
mov cs:[di],dx ;将寄存器中的机器码给到cs:[di](也就是s0段对应的首地址)
s0: nop ;一个nop占一个字节
nop
9.2jmp指令
jmp无条件转移指令,可以指修改ip也可以同时修改ip和cs
jmp要给出两种信息
(1)转移的目的地址
(2)转移的距离(段间转移、段内短转移、段内近转移)
9.3依据位移进行位移的jmp指令
jmp short 标号(转到标号处执行指令)
段内短转移 ip修改范围-128~127
一般的指令中的数据(立即数),或者内存单元的偏移地址都会在对那个的机器指令中出现
如下图所示
如图所示jmp对应的机器码是EB03 jmp s 表示为jmp0008(inc ax)
CPU指令的执行过程
CS:IP通过地址加法器进行(cs*16(10)+ip)换算出物理地址
地址加法器将物理地址送入输入输出控制电路
输入输出控制电路将换算出的物理地址送入地址总线(20位)
将相应的内存单元中的数据(指令对应机器码)通过数据总线送入输入输出控制电路
输入输出控制电路将机器码送入cpu指令缓冲器
读取一条指令后ip=ip+所读指令长度(也就是说指向下一个机器指令)
最后cpu指令缓冲器将机器码送入执行控制器执行
以下内容来自于王爽老师所著汇编语言第四版
实际上jmp的指令执行过程是这样的:
jmp short 标号
ip=ip+8位位移
(1)8位位移=标号的偏移地址-jmp指令的下一条指令的第一个字节的地址
(2)short指明为8位位移
(3)8位位移范围是-128~127用补码表示
(4)8位位移由编译程序在编译时算出
jmp near ptr 标号
功能:ip=ip+16位位移
(1)16位位移=标号的偏移地址-jmp指令的下一条指令的第一个字节的地址
(2)near ptr 指明为16位位移
(3)16位位移范围是--32768~32767用补码表示
(4)16位位移由编译程序在编译时算出
(补码)
我所理解的就是:补码实际上就是一种数据的表达方式
他的出现就是为了表示有符号并且解决0的两种表达方式问题
当给我们一个(负数)补码的时候我们不好判断出来它的数值,
但是我们可以根据
复数的补码取反加一后是他本身的绝对值
这一性质推算出他所代表的值
8位补码的范围依旧是-128~127
应该知道的是补码最高位是1代表符数 0代表正数
9.4转移的目的地址在指令中的jmp指令
前边讲的jmp指令,其对应的机器指令中并没有转移的目的地址,而是相对于当前的ip的转移位移
jmp far ptr 标号
实现的是段间转移,有称之为远转移,功能:CS=标号在段中的段地址 IP=标号在段中的偏移地址,far ptr 指明改变CS和IP
code segment
start: mov ax,0
mov bx,0
jmp far ptr s
db 256 dup(0)
s:inc ax
mov ax,4C00h
int 21h
code ends
再添加一条jmp
code segment
start: mov ax,0
mov bx,0
jmp far ptr s
db 256 dup(0)
s:inc ax
jmp far ptr s
mov ax,4C00h
int 21h
code ends
这条指令翻译出来后和原来的一样
9.5转移地址在寄存器中的jmp指令
jmp 16位寄存器
ip=16位寄存器
因为都是寄存器所以不用反高低位
9.6转移地址在内存中的jmp指令
转移地址在内存中的jmp指令有两种格式:
(1)jmp word ptr 内存单元地址(段内转移)
要注意高低位
(2)jmp dword ptr 内存单元地址 (段间转移)
低16位给IP
高16位给CS
9.7JCXZ指令
jcxz转移指令为条件转移指令,所有的条件转移指令均为短转移,对应机器码中包含的是转移的位移,而不是目的地址,对IP的修改范围是-128~127
格式:jcxz 标号 如果cx=0转移到标号处ip指到标号处执行
操作:当(cx)=0时,(IP)=(IP)+8位位移
8位位移=标号处的地址-jcxz指令后的第一个字节地址:
8位位移的范围为-128~127,用补码表示
8位位移有编译程序在编译时算出
jcxz 标号的功能相当于C语言中
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
什么也不做程序向下进行
c:
(cx)--;
if((cx)!=0)
jmp short 标号;
9.9根据位移进行转移的意义
jmp short 标号
jmp near ptr 标号
jcxz 标号
loop 标号
修改IP是根据位移修改
优点:代码可以移动,不会出现错误
9.10编译器对转移位移超解的检测
jmp short s 的转移范围是-128~127
如果超出范围则会编译出错
曾经jmp 2000:0100的指令直接在debug中使用汇编编译器不认识,如果在源程序中使用也会编译出错