2021-10-13 10:17:10

转移指令的原理-汇编8086-读书笔记9

9 转移指令的原理

[TOC]

可以修改IP, 或同时修改CS和IP的指令统称为转移指令。

8086CPU的转移行为有以下几类:

  • 只修改IP时,称为段内转移。如jmp ax
  • 同时修改CS和IP时, 称为段间转移,比如:jmp 1000:0

转移指令对IP的修改范围不同,段内转移可进一步分为:短转移和近转移

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

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

  • 无条件跳转指令(如jmp)
  • 条件转移指令(如jnz)
  • 循环指令(如loop)
  • 过程 (如call,ret)
  • 中断(int)

操作符offset

操作符offset在汇编语言中是由编译器处理的符号,它的功能是取得标号的偏移地址。比如下面的程序:

assume cs:codesg
codesg segment
start: mov ax, offset start; 相当于mov ax, 0
		s: mov ax, offset s  ;相当于mov ax, 3; 我不清楚一条指令到底多长,这种情况下加个标号,使用offset 就可以了。编译器会帮你计算。想知道对应指令的机器码可以用debug查看。
codesg ends
end start

jmp指令

无条件跳转指令,可修改IP,也可同时修改CS和IP。

jmp指令要给出两种信息:

  1. 转移的目的地址。
  2. 转移的距离(段间转移、段内短转移、段内近转移)

总结

目的地址 示例 说明
无,有偏移地址 jmp short 标号 偏移地址在机器码中 EBXXXX XXXX为偏移地址
有,在指令中 jmp far ptr 标号 目的地址在机器码中 EAXXXXYYYY XXXX为段地址,YYYY为偏移地址
有,在寄存器中 jmp 16位 reg 目的地址在寄存器中。用于修改IP
有,在内存中

依据位移进行转移的jmp指令

段内短转移:jmp short 标号

对IP的修改范围-128~127

CPU在执行jmp指令的时候并不需要转移的目的地址。

jmp short 标号生成的机器码为EBXX, 其中XX指明了下一个指令和目标指令的偏移量。于是直接IP=IP+偏移量就计算出了目的地址。

实际上,jmp short 标号的功能为:(IP) = (IP)+8位位移。

  1. 8位位移=标号处的地址-jmp 指令后的第一个字节的地址;
  2. short 指令此处的位移为8位位移。
  3. 8位位移的范围为-128~127, 用补码表示。
  4. 8位位移由编译程序在编译时算出。。

类似的jmp near 标号使用的位移为16位位移。

图实例:

image-20210916205729732

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

jmp far ptr 标号 段间转移,跨段了,没法计算偏移量,所以必须制定目的地址了。

(cs)=标号所在段的段地址;(IP)=标号在段中的偏移地址。

jmp far ptr 标号对应的机器码为EAXXXXYYYY 其中XXXX为段地址,YYYY为偏移地址。

转移地址在寄存器中的jmp指令

指令格式:jmp 16位 reg

功能:(IP)=(16位reg)

转移地址在内存中的jmp指令

两种形式:

  1. 段内转移 jmp word ptr 内存单元地址 内存单元存的偏移地址
  2. 段间转移jmp dword prt 内存单元地址 内存单元存2个字,高地址是段地址,低地址是偏移地址。

jcxz指令

条件转移。jcxz 标号

类似jmp short 标号 也是把偏移地址放到指令中。

如果(cx)==0 跳转到标号。否则什么都不干,

loop指令

也是短转移。偏移地址放到指令中。

执行loop 标号

  1. (cx)=(cx)-1
  2. 如果(cx)!=0 跳转到标号。否则什么都不干。(程序向下执行)

根据位移进行转移的意义

总结下使用位移跳转的指令:

  1. jmp short 标号
  2. jmp near ptr 标号
  3. jczx 标号
  4. loop 标号

这种设计方便程序段在内存中浮动装配。

其实有虚拟内存之后。这个设计的意义感觉就不大了?

编译器对转移位移越界的检测

转移范围是-128-127 如果越界,编译器会报错。在Debug中不会。

本文链接:http://blog.go2live.cn/post/assemble-9.html

-- EOF --