【汇编语言】转移指令的原理(三) —— 汇编跳转指南:jcxz、loop与位移的深度解读

文章目录

  • 前言
  • [1. jcxz 指令](#1. jcxz 指令)
    • [1.1 什么是jcxz指令](#1.1 什么是jcxz指令)
    • [1.2 如何操作](#1.2 如何操作)
  • [2. loop 指令](#2. loop 指令)
    • [2.1 什么是loop指令](#2.1 什么是loop指令)
    • [2.2 如何操作](#2.2 如何操作)
  • [3. 根据位移进行转移的意义](#3. 根据位移进行转移的意义)
    • [3.1 为什么?](#3.1 为什么?)
    • [3.2 举例说明](#3.2 举例说明)
  • [4. 编译器对转移位移超界的检测](#4. 编译器对转移位移超界的检测)
  • 结语

前言

📌

汇编语言是很多相关课程(如数据结构、操作系统、微机原理)的重要基础。但仅仅从课程的角度出发就太片面了,其实学习汇编语言可以深入理解计算机底层工作原理,提升代码效率,尤其在嵌入式系统和性能优化方面有重要作用。此外,它在逆向工程和安全领域不可或缺,帮助分析软件运行机制并增强漏洞修复能力。

本专栏的汇编语言学习章节主要是依据王爽老师的《汇编语言》来写的,和书中一样为了使学习的过程容易展开,我们采用以8086CPU为中央处理器的PC机来进行学习。

1. jcxz 指令

1.1 什么是jcxz指令

jcxz指令为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。

对IP的修改范围都为-128~127。

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

1.2 如何操作

"jcxz 标号"指令操作:

  • 当(cx)=0时,(IP)=(IP)+8位位移;

  • 8位位移="标号"处的地址 - jcxz指令后的第一个字节的地址;

  • 8位位移的范围为-128~127,用补码表示;

  • 8位位移由编译程序在编译时算出。

  • 当(cx)=0时,什么也不做(程序向下执行)。

我们从 jcxz的功能中可以看出,指令"jcxz 标号"的功能相当于:

if((cx)==0) jmp short 标号;

(这种用C语言和汇编语言进行的综合描述,或许能使你对有条件指令理解得更加清楚。)

2. loop 指令

2.1 什么是loop指令

loop指令为循环指令,所有的循环指令都是短转移,在对应的机器码中包含转移的位移,而不是目的地址。

对IP的修改范围都为-128~127。

指令格式:loop 标号((cx))=(cx)-1,如果(cx)≠0,转移到标号处执行。)

2.2 如何操作

"loop 标号"指令操作:

(1)(cx)=(cx)-1;

(2)如果(cx)≠0,(IP)=(IP)+8位位移。

  • 8位位移="标号"处的地址-loop指令后的第一个字节的地址;

  • 8位位移的范围为-128~127,用补码表示;

  • 8位位移由编译程序在编译时算出。

  • 当(cx)=0,什么也不做(程序向下执行)。

我们从loop的功能中可以看出,指令"loop 标号"的功能相当于:

(cx)--;

if((cx)≠0) jmp short 标号;

3. 根据位移进行转移的意义

3.1 为什么?

前面我们讲到:

assembly 复制代码
jmp short 标号
jmp near ptr 标号
jcxz 标号
loop 标号

等几种汇编指令,它们对 IP的修改是根据转移目的地址和转移起始地址之间的位移来进行的。

在它们对应的机器码中不包含转移的目的地址,而包含的是到目的地址的位移距离。

这样设计,方便了程序段在内存中的浮动装配。

3.2 举例说明

例如:

这段程序装在内存中的不同位置都可正确执行,因为 loop s 在执行时只涉及到s的位移( - 4,前移 4个字节,补码表示为FCH),而不是s的地址。

如果loop s的机器码中包含的是s的地址,则就对程序段在内存中的偏移地址有了严格的限制;因为机器码中包含的是 s 的地址,如果 s 处的指令不在目的地址处,程序的执行就会出错。

而loop s的机器码中包含的是转移的位移,就不存在这个问题了;因为,无论 s 处的指令的实际地址是多少,loop指令的转移位移是不变的。

4. 编译器对转移位移超界的检测

注意,根据位移进行转移的指令,它们的转移范围受到转移位移的限制,如果在源程序中出现了转移范围超界的问题,在编译的时候,编译器将报错。

比如,下面的程序将引起编译错误:

assembly 复制代码
assume cs:code

code segment
start:	jmp short s
	db  128 dup(0)
    s:	mov ax,0ffffh
code ends

end start

报错如下:

jmp shorts的转移范围是-128~127,IP最多向后移动127 个字节,

我们在前面的文章中讲到的形如"jmp 2000:0100"的转移指令,是在 Debug 中使用的汇编指令,汇编编译器并不认识。如果在源程序中使用,编译时也会报错。

结语

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。

也可以点点关注,避免以后找不到我哦!

Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!

相关推荐
如若1238 分钟前
TRACER 论文解读与复现:面向 ICU 长时程患者监测的多模态 Harness 架构、时序证据建模与工具增强推理
人工智能·深度学习·计算机视觉
深蓝AI2 小时前
无头浏览器不必从 Chrome 改:Lightpanda 用 Zig 从零造,100 个页面只占 123MB 内存
人工智能·程序员
奈落244 小时前
AI辅助的另一面:从2026年国际AI安全报告的“故障”清单到国内专家的可靠性短板,自主行动的Agent为什么更难及时干预
人工智能·安全·agent·本地部署·ai 办公
火山引擎开发者社区6 小时前
eMudhra 证书失陷:容器用户最容易忽略的镜像信任链漏洞
人工智能
LabVIEW开发7 小时前
LabVIEW 机载 DIAL:每秒万次甲烷测量
人工智能·labview·labview知识·labview功能·labview程序
飞猫的边缘AI8 小时前
英特尔量子生意
人工智能·量子计算·边缘ai
深蓝AI8 小时前
桌面 Agent 缺的不是视觉:Vercel 开源 agent-desktop,用无障碍树 ref 替代截图坐标
人工智能·程序员
镜子AI8 小时前
镜子AI 技术复盘:三条自动化链路上的“停止条件“设计
运维·人工智能·自动化
我不会起名字3228 小时前
Redis 从 0 到 1(十七):订单 30 分钟不支付自动关闭——ZSet 延迟队列 Go 实现
redis·go·延迟队列·zset·订单
向哆哆8 小时前
羊行为目标检测数据集:4类别、2,000张图像 | 目标检测
人工智能·yolo·目标检测·目标跟踪