章节目录

  1. 转移指令原理
  2. jmp 指令
  3. jcxz 指令
  4. loop 指令
  5. ret 和 retf 指令
  6. call 指令
  7. call+ret

作者能力有限, 如果您在阅读过程中发现任何错误, 还请您务必联系本人,指出错误, 避免后来读者再学习错误的知识.谢谢!

本文中所有程序均在DOSBox下使用MASM, LINK编译运行

转移指令原理

转移指令是可以控制 CPU 执行内存中某处代码的指令. 而 CPU 执行内存中哪处的指令是由 CS 和 IP 寄存器中的决定的. 因此, 转移指令是通过修改 CS 和 IP 寄存器的值来控制 CPU 对指令的执行的.

只修改 IP 的转移行为称为 段内转移.
同时修改 CS 和 IP 的转移行为称为 段间转移.

由于转移指令对 IP 的修改范围不同, 段内转移又分为: 短转移和近转移.
短转移: 对 IP 修改范围为 -128 ~ 127.
近转移: 对 IP 修改范围为 -32768 ~ 32767.

jmp 指令

jmp为无条件转移指令, 可以修改 IP 或者同时修改 CS 和 IP.

jmp short 标号

这条指令完成段内短转移. 对 IP 的修改范围为:-128 ~ 127. 执行完该指令之后, CS 的值不变, IP 指向标号在段中的偏移地址.

示例:

在上面程序中我们通过 jmp short s 将 IP 指向标号 s 的偏移地址. 当程序执行到 jmp 时, 会直接跳转到 s 处, 从 s 处继续往下执行.

jmp far ptr 标号

这条指令完成段间转移, 又称为远转移. 执行完该指令之后, CS 指向标号所在的段基址, IP 指向标号在段中的偏移地址.

示例:

在上面程序中我们通过 jmp far ptr s 将 CS 指向标号 s 的段基址, IP 指向标号 s 的偏移地址. 当程序执行到 jmp 时, 会直接跳转到 s 处, 从 s 处继续往下执行.

其他 jmp 指令

当然转移地址可以存储在寄存器或者内存中, 相应的语法如下:

jmp reg // 其中 reg 为 16位寄存器,其中存储这要跳转的偏移地址.

jmp word ptr 内存单元地址 // 段内转移, 内存单元存放目的偏移地址.
// 示例:
mov ax, 0123H
mov ds:[0], ax
jmp word ptr [ds]:[0] // IP = 0123H

jmp dword ptr 内存单元地址 // 段间转移, 内存单元两个字节,
//高地址处存放着转移的目的段基址, 低字节存放的是转移的目的偏移地址.
// 示例:
mov ax, 0123H
mov ds:[0], ax
mov word ptr ds:[2], 0
jmp word ptr [ds]:[0] // CS = 0, IP = 0123H

Note: 转移指令,不仅仅可以向后跳转, 亦可以向前跳转.

jcxz 指令

该指令为有条件转移指令. 所有有条件转移指令都是短转移.

指令格式: jcxz 标号(如果 CX = 0, 转移到标号处执行)

jcxz 的功能相当于: if (CX == 0) jmp short 标号
当 CX != 0 时, jcxz 什么也不做, 程序继续向下执行.

示例:

loop 指令

该指令在上一篇文章中已经涉及,示例可参考汇编语言笔记(一)

ret 和 retf 指令

ret 指令用栈中的数据, 修改 IP 的值, 实现近转移.
retf 指令用栈中的数据, 修改 CS 和 IP 的值, 实现远转移.

CPU 执行 ret 指令时, 进行如下两步操作:

IP = SS * 16 + SP
SP = SP + 2

相当于: pop IP

CPU 执行 retf 执行时, 进行如下四步操作:

IP = SS * 16 + SP
SP = SP + 2
CS = SS * 16 + SP
SP = SP + 2

相当于:
pop IP
pop CS

示例:

ret 用法

retf 用法:

上述程序中, ret/retf 执行执行后, IP = 0, CS:IP 指向代码段的第一条指令.

call 指令

CPU 执行 call 指令时, 执行以下两步操作:

将当前的 IP 或者 CS 和 IP 压入栈中
转移

call 指令不能实现短转移.

call 标号

CPU 执行此指令时, 执行如下操作:

(1) SP = SP - 2, SS * 16 + SP = IP
(2) IP = IP + 16 位位移

执行 call 标号 指令相当于执行:
push IP
jmp near ptr 标号

call far ptr 标号

CPU 执行此指令时, 执行如下操作:

(1) SP = SP - 2, SS * 16 + SP = CS
SP = SP - 2, SS * 16 + SP = IP
(2) CS = 标号所在段的段基址
IP = 标号在段中的偏移地址

执行 call far ptr 标号 指令相当于执行:
push CS
push IP
jmp far ptr 标号

其他 call 指令

当然转移地址可以存储在寄存器或者内存中, 相应的语法如下:

call reg

reg 为16位寄存器
相应 CPU 操作:
SP = SP - 2, SS * 16 + SP = IP
IP = reg 中的值
相当于:
push IP
jmp reg

call word ptr 内存单元地址

相当于:
push IP
jmp word ptr 内存单元地址
示例:
mov sp, 10H
mov ax, 0123H
mov ds:[0], ax
call word ptr ds:[0] // 执行后 IP = 0123H, SP=0EH

call dword ptr 内存单元地址

相当于:
push CS
push IP
jmp dword ptr 内存单元地址
示例:
mov sp, 10H
mov ax, 0123H
mov ds:[0], ax
mov word ptr ds:[2], 0
call word ptr ds:[0] // 执行后 CS=0, IP = 0123H, SP=0CH

call + ret

建议在继续往下看之前, 仔细阅读一下上图中代码, 分析程序结束时 bx 中的值是多少?

分析一下这个程序将非常有助于我们理解 call 和 ret 指令.

(1) 程序执行到 call s 时, IP 此时指向了 call s 的下一条指令 mov bx, ax (CS 和 IP 指向了 CPU 当前要读取指令的地址. 而当前已经执行到了 call s,因此下一条要读取的指令将是 mov bx, ax);
(2) CPU 执行 call s 时, 将当前 IP 值(指向 mov bx, ax 的偏移地址)压栈, 并将 IP 的值改变为标号 s 的偏移地址.
(3) CPU 从标号 s 处开始执行指令, loop 循环结束后, ax = 8
(4) CPU 将 ret 指令读入, IP 指向了 ret 指令后的内存单元(此时仅仅是读取指令,还未执行 ret 指令);
(5) CPU 执行 ret 指令, 从栈中弹出一个值(即 call s 指令先前压入的 mov bx, ax 指向的偏移地址), 将该值存入 IP 中. 此时 CS:IP 指向指令 mov bx, ax.
(6) 执行完 ret 指令之后, 程序将跳转到 mov bx, ax 处继续执行, 直至完成.
(7) 最终, bx = 8.

欢迎交流任何想法.

End…

1

汇编学习笔记(二):转移指令相关推荐

  1. 汇编学习笔记——汇编指令

    目录 汇编指令 nop指令 mov.add.sub指令 adc.sbb指令 and.or指令 移位指令 逻辑左/右移指令 循环左/右移指令 算术左/右移指令 带进位循环左/右移指令 inc指令 pus ...

  2. qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7851 ...

  3. [转载]dorado学习笔记(二)

    原文地址:dorado学习笔记(二)作者:傻掛 ·isFirst, isLast在什么情况下使用?在遍历dataset的时候会用到 ·dorado执行的顺序,首先由jsp发送请求,调用相关的ViewM ...

  4. PyTorch学习笔记(二)——回归

    PyTorch学习笔记(二)--回归 本文主要是用PyTorch来实现一个简单的回归任务. 编辑器:spyder 1.引入相应的包及生成伪数据 import torch import torch.nn ...

  5. tensorflow学习笔记二——建立一个简单的神经网络拟合二次函数

    tensorflow学习笔记二--建立一个简单的神经网络 2016-09-23 16:04 2973人阅读 评论(2) 收藏 举报  分类: tensorflow(4)  目录(?)[+] 本笔记目的 ...

  6. Scapy学习笔记二

    Scapy学习笔记二 Scapy Sniffer的用法: http://blog.csdn.net/qwertyupoiuytr/article/details/54670489 Scapy Snif ...

  7. Ethernet/IP 学习笔记二

    Ethernet/IP 学习笔记二 原文链接:http://wiki.mbalib.com/wiki/Ethernet/IP 1.通信模式 不同于源/目的通信模式,EtherNet/IP 采用生产/消 ...

  8. Java学习笔记二:数据类型

    Java学习笔记二:数据类型 1. 整型:没有小数部分,允许为负数,Java整型分4种:int short long byte 1.1 Int最为常用,一个Int类型变量在内存中占用4个字节,取值范围 ...

  9. 吴恩达《机器学习》学习笔记二——单变量线性回归

    吴恩达<机器学习>学习笔记二--单变量线性回归 一. 模型描述 二. 代价函数 1.代价函数和目标函数的引出 2.代价函数的理解(单变量) 3.代价函数的理解(两个参数) 三. 梯度下降- ...

最新文章

  1. 曝光机与曝光能量_LED曝光机
  2. 刚刚,三名中国航天员奔赴太空!其中一位刚参加完博士毕业典礼!
  3. hbase put 异步 java_java – HBase BufferedMutator vs PutList性能
  4. python爬虫——随机生成headers
  5. 又一轮电邮中间人攻击来袭 企业如何自保?
  6. QDoc支持衍生项目
  7. vue 如何获取图片的原图尺寸_公众号封面图片尺寸是多少?如何在公众号里制作封面图?...
  8. Pandas知识点-合并操作join
  9. 关于sql备份到其他服务器的问题
  10. 【图像隐写】基于matlab GUI变换域的可逆数字水印系统设计【含Matlab源码 1813期】
  11. VS 配置Directx
  12. R语言编程技术(2)
  13. 图片怎样编辑文字?分享三个图片编辑修改文字的方法
  14. 启动docker-compose时报/usr/lib/python2.7/site-packages/requests/__init__.py:91: RequestsDependencyWarnin
  15. 传递关系的复合不一定是传递的
  16. 半同步半异步模式 -------一个架构模式,清晰的结构,高效并发的I/O
  17. Snagit_日文输入法:促音,长音,小写的输入方法
  18. Linux服务器怎么关闭防火墙?
  19. html5中的meter标签改变颜色规则
  20. 365天挑战LeetCode1000题——Day 126 单调栈模板 500题纪念

热门文章

  1. PHP+MySQL 跨服务器跨数据库数据拷贝系统
  2. python opencv3 检测人
  3. [机器学习] Apriori算法
  4. PHP中的中文截取乱码问题_gb2312_utf-8
  5. APL开发日志--2013-01-17
  6. 获得SD卡的剩余容量
  7. 数据结构C语言实现—队列操作
  8. [导入]将Byte数组转化为String
  9. 牛客14386 水仙花数
  10. Python程序生成.exe的可执行文件