当前位置: 首页 > article >正文

跳转指令四维全解:从【call/jmp 】的时空法则到内存迷宫导航术

一、核心概念:代码世界的空间定位法则

在汇编世界里,我们可以把内存想象成一栋巨大的图书馆:

  • CS(代码段寄存器) = 楼层编号

  • IP(指令指针) = 房间编号

  • 当前执行位置 = CS:IP(如3楼201室)

寻址方式对比表:

类型比喻修改的寄存器地址来源特点
近(Near)同一楼层换房间只改IP相对/绝对不换代码段
远(Far)跨楼层跳转同时改CS和IP绝对切换代码段
相对(Relative)"向前走10步"IP偏移量位置相关
绝对(Absolute)"去3楼201室"CS和/或IP固定地址位置无关
直接(Direct)按门牌号找人-指令内硬编码高效但死板
间接(Indirect)看小纸条找人-寄存器/内存灵活但稍慢

二、call指令:带返程票的智能跳转

1. 相对近调用:同一楼层的短途出差

; 当前在CS:100处
102 call near proc1  ; 出门前记下返程票(IP=103)   
103 ........
............
150 proc1:           ; 目标地址(IP=150)mov ax, bxret          ; 凭票返回

  • 特点

    • 偏移范围:±32KB(16位有符号数)

    • 执行时:push IPIP = IP + 偏移

    • 返回时:ret弹出IP继续执行

2. 间接绝对近调用:按便签跳转

mov bx, 0x300  ; 便签写着房间号300
call bx        ; 跳转到CS:300; 或从内存读取地址
call [func_ptr] ; func_ptr内存存着目标地址
  • 内存布局示例

    0x200: 78 56  ; 小端存储 IP=0x5678
    0x202: 34 12  ; 小端存储 CS=0x1234 (远调用用)

3. 直接远调用:跨楼层硬编码跳转

call 0x2000:0x0500 ; 去2楼500室
; 压栈顺序:先CS后IP
  • 栈变化

         执行前栈顶 → ??执行后栈顶 → 旧IP→ 旧CS

4. 间接远调用:跨楼层看便签

; 内存0x1000处存放目标地址
call far [0x1000] ; 相当于:
;   IP = [0x1000] 
;   CS = [0x1002]

 

  • 应用场景

    • 动态加载库函数

    • 操作系统任务切换

    • DOS中断处理(INT 21h)

总结

  • 压栈是 call 的必然行为,与后续是否有 ret/retf 无关。
  • ret/retf 的作用:弹出返回地址,让程序回到调用点。若无这两条指令,程序无法正常返回,栈会逐渐溢出,最终崩溃。

简单说:call 负责 “存钱(压栈)”,ret/retf 负责 “取钱(弹出)”,即使你不取钱,钱也会被存进银行(栈)。

扩展 

    call和ret/retf一定成对才可以使用吗?call不用ret/retf最多不返回,那ret/retf单独可以用吗?

        可以,我们可以模仿call指令压栈,比如远调用依次压入cs和ip,当执行retf时,就会依次弹出到cs和ip。当然也可以模仿近调用压入ip,当执行ret,就会弹出到ip。所以说不一定非要成对使用的。    


三、jmp指令:说走就走的旅行

1. 相对短跳转:隔壁房间串门

jmp short label  ; ±128字节范围
label:nop
  • 机器码EB xx(xx为1字节偏移)

  • 典型用途:跳过小段代码

    cmp ax, 0
    jz short zero_case  ; 条件跳转都是相对短

2. 相对近跳转:同层自由行

jmp near target  ; ±32KB范围
target:mov cx, 100
  • 循环中的经典应用

       mov cx, 10
    loop_start:dec cxjnz near loop_start  ; 循环跳转

3. 间接绝对近跳转:看便签找房间

jmp bx     ; 跳转到CS:BXjmp [table+si] ; 查表跳转
  • 跳转表实现

    jmp_table dw func1, func2, func3mov si, 2  ; 选择功能2
    jmp [jmp_table+si*2]

4. 直接远跳转:跨楼层硬闯

jmp 0x5000:0x0100 ; 直接去5楼100室
  • Bootloader应用

    ; 从引导扇区跳转到内核
    jmp 0x1000:0x0000 

5. 间接远跳转:跨楼层看导航

jmp far [0x2000] ; 从0x2000读取CS:IP
  • 系统调用实现

    ; 设置系统调用入口
    mov word [0x1000], 0x00    ; IP
    mov word [0x1002], 0x07C0  ; CS; 执行系统调用
    jmp far [0x1000]

总结

jmp 是 “单程票”,跳转后无法返回,因此无需压栈;而 call 是 “往返票”,必须压栈保存返回地址才能回来。这是两者的本质区别。


四、核心机制对比

1. 跳转范围矩阵

指令类型同段范围跨段能力
短跳转(jmp)256字节×
近跳转(jmp/call)64KB×
远跳转(jmp/call)整个内存空间

2. 栈操作差异

3. 性能对比

寻址方式时钟周期特点
寄存器间接跳转2-4最快
内存间接跳转5-10需内存访问
远跳转10-15涉及段寄存器加载
相对跳转3-5适合位置相关代码

五、实战技巧与陷阱

1. call/ret平衡法则

; 正确示例
func:push bpmov bp, sp... ; 操作pop bpret; 错误示例(栈不平衡)
bug_func:push axpush bx... pop ax  ; 应该先pop bx!ret     ; 返回地址错误!

2. 跨段跳转黄金守则

; 远调用前必须设置栈
mov ax, new_stack_seg
mov ss, ax
mov sp, 0xFFFEcall far new_seg:func; 返回后恢复原栈
mov ax, old_stack_seg
mov ss, ax
mov sp, old_sp

3. 动态跳转最佳实践

; 安全查表跳转
cmp al, MAX_FUNC_ID
ja invalid_func
mov bx, al
shl bx, 1      ; 乘2(字偏移)
jmp [jump_table+bx]invalid_func:; 错误处理

六、现代演进:从实模式到保护模式

1. 32位扩展变化

特性16位实模式32位保护模式
偏移范围64KB4GB
调用类型near/far平坦模式只有near
间接跳转寄存器/内存增加任务门调用
返回指令ret/retfret/retf带立即数

2. 保护模式间接调用

; 通过调用门选择子
call 0x0010:0x00000000 ; 实际跳转过程:
; 1. 查GDT获取调用门描述符
; 2. 权限检查
; 3. 加载目标CS:EIP

3. 64位架构革新

; RIP相对寻址成为主流
lea rax, [rel target]  ; 相对偏移
jmp rax                ; 寄存器间接; 直接跳转范围扩大到±2GB
call qword 0xFFFF_FFFF_1234_5678

结语:掌握跳转艺术的四维法则

  1. 空间维度

    • 近跳转:当前楼层内活动

    • 远跳转:跨楼层探索

  2. 时间维度

    • call:记住来时路(有返回)

    • jmp:勇往直前(无返回)

  3. 定位方式

    • 相对:以我为基准

    • 绝对:全局坐标系

  4. 目标解析

    • 直接:地址写在指令中

    • 间接:运行时动态确定

掌握这四维法则,你就能在汇编世界的内存迷宫中自由穿梭。下次写汇编时,只需问自己四个问题:
① 要不要回来?(call/jmp)
② 要不要换楼层?(near/far)
③ 目标在哪?(相对/绝对)
④ 地址怎么给?(直接/间接)

答案自然浮现,跳转如此简单!

 

相关文章:

跳转指令四维全解:从【call/jmp 】的时空法则到内存迷宫导航术

一、核心概念:代码世界的空间定位法则 在汇编世界里,我们可以把内存想象成一栋巨大的图书馆: CS(代码段寄存器) 楼层编号 IP(指令指针) 房间编号 当前执行位置 CS:IP(如3楼201…...

LabVIEW实时系统数据监控与本地存储

基于LabVIEW Real-Time 模块,面向工业自动化、嵌入式测控等场景,提供实时数据采集、监控与本地存储的完整实现路径。通过分层任务调度、TDMS 文件格式应用及跨平台兼容性设计,确保系统在实时性、可靠性与数据管理效率间达到平衡。文中以 Comp…...

从 Revit 到 3DTiles:GISBox RVT 切片器如何让建筑图元在 Web 端展示

在GIS(地理信息系统)行业蓬勃发展的当下,数据处理与展示的效率和精准度成为关键。GISBox作为一款功能强大的一站式三维GIS数据编辑、转换、发布平台,凭借其独特的“RVT切片器”功能,在RVT图元处理方面也有着不俗的表现…...

Appium+python自动化(十二)- Android UIAutomator

Android团队在4.1版本(API 16)中推出了一款全新的UI自动化测试工具UiAutomator,用来帮助开发人员更有效率的完成App的Debug工作,同时对于测试人员也是一大福音,为什么这么说呢? UiAutomator提供了以下两种…...

在C语言中使用UUID作为AES加密密钥

在C语言中使用UUID作为AES加密密钥 编译依赖安装示例代码编译和运行关键点说明![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/0df1f1d803cd40688f6d58a9d0e1f1d9.png)注意事项编译依赖安装 运行环境位centos8 Linux 4.18.0-348.7.1.el8_5.x86_64 #1 SMP Wed Dec …...

Nginx+Tomcat负载均衡集群

目录 一、Tomcat 基础与单节点部署 (一)Tomcat 概述 (二)单节点部署案例 1. 案例环境 2. 实施准备 3. 安装 JDK 4. 查看 JDK 安装情况 5. 安装配置 Tomcat 6. 启动 Tomcat 7. 访问测试 8. 关闭 Tomcat (三…...

QQ邮箱发送验证码(Springboot)

一、邮箱发送服务准备 在qq邮箱的设置中选择账号下开启服务。 开启时可能会有短信验证,开启后显示验证码之类的一串英文,复制保存起来,在配置文件中会使用到。 二、后端依赖及配置 依赖 在pom.yml文件中添加相关依赖,redis的…...

Python Copilot【代码辅助工具】 简介

粉丝爱买鳕鱼肠深海鳕鱼肉鱼肉香肠盼盼麦香鸡味块卡乐比(Calbee)薯条三兄弟 独立小包美丽雅 奶茶杯一次性饮料杯好时kisses多口味巧克力糖老金磨方【黑金系列】黑芝麻丸郑新初网红郑新初烤鲜牛肉干超人毛球修剪器去球器剃毛器衣服去毛器优惠券宁之春 红黑…...

如何写高效的Prompt?

概述 提示词(Prompt)的质量将直接影响模型生成结果的质量,所以精心设计一个让大模型能够理解并有效回复的提示词是至关重要的。本文内容自论文中获取:https://arxiv.org/pdf/2312.16171 介绍了5类共计26条提示词书写原则。 书写原则 类别原则备注快速…...

【EF Core】 EF Core并发控制:乐观锁与悲观锁的应用

文章目录 前言一、并发的风险二、EF Core中的并发控制方式2.1 开放式并发(乐观锁)2.1.1 应用程序管理的属性并发令牌2.1.2 数据库生成的并发令牌 2.2 悲观锁 总结 前言 实际的生产环境中,我们经常能遇到数据库由多个应用程序同时使用。每个程…...

WaytoAGI东京大会开启AI全球化新对话:技术无国界,合作促创新

全球AI专家齐聚东京,一场关于技术无国界的对话正在进行。 2025年6月7日,一场备受瞩目的AI盛会——“WaytoAGI全球AI大会东京站”在日本东京樱美林大学新宿校区正式拉开帷幕。这场为期两天的会议(6月7日至8日)由国内最大的AI开源知…...

Harmony核心:动态方法修补与.NET游戏Mod开发

一、Harmony的核心定位与设计哲学 Harmony是一个运行时动态方法修补库,专为修改已编译的.NET/Mono应用程序而设计,尤其适用于游戏Mod开发。其核心创新在于: 非破坏性修改:保留原始方法完整性,避免直接替换或覆盖。多…...

AI系统应用开发工程师

以下是对AI系统应用开发与运维岗位的梳理整合,从企业、岗位、任务、能力等维度进行分类呈现,便于清晰对比两者的工作侧重: 一、代表性企业对比 分类企业名称应用开发方向中移系统集成有限公司、科大讯飞河北科技有限公司、华为技术服务有限…...

Qt Test功能及架构

Qt Test 是 Qt 框架中的单元测试模块,在 Qt 6.0 中提供了全面的测试功能。 一、主要功能 核心功能 1. 单元测试框架 提供完整的单元测试基础设施 支持测试用例、测试套件的组织和执行 包含断言宏和测试结果收集 2. 测试类型支持 单元测试:对单个函…...

图像处理、图像分析和图像理解的定义、联系与区别

1. 定义 图像处理(Image Processing) 图像处理是低层操作,主要针对像素级的图像数据进行加工,目的是改善图像质量或为后续分析做准备。 典型任务:去噪、增强(如对比度调整)、锐化、边缘检测、图…...

【Java开发日记】说一说 SpringBoot 中 CommandLineRunner

目录 1、CommandLineRunner SpringBoot中CommandLineRunner的作用 简单例子 多个类实现CommandLineRunner接口执行顺序的保证 通过实现Ordered接口实现控制执行顺序 通过Order注解实现控制执行顺序 Order 作用 2、ApplicationRunner 3、传递参数 4、源码跟踪 run()方…...

全面理解 Linux 内核性能问题:分类、实战与调优策略

在 Linux 系统(特别是嵌入式或服务器环境)中,性能问题往往错综复杂、表象多变。只有对常见性能问题进行系统归类、理解其症状与根源,才能有效定位和解决。本文将围绕八大类核心性能问题,结合实战示例,逐类分…...

算法-多条件排序

1、数对排序的使用 pair<ll,ll> a[31];//cmp为比较规则 ll cmp(pair<ll,ll>a,pair<ll,ll>b){if(a.first!b.first)return a.first>b.first;else return a.second<b.second; }//按照比较规则进行排序 sort(a1,a31,cmp); 2、具体例题 输入样例&#xff1…...

DelayQueue、ScheduledThreadPoolExecutor 和 PriorityBlockingQueue :怎么利用堆实现定时任务

DelayQueue DelayQueue 的最大亮点&#xff1a; 并不是简单全局锁的“单调队列”实现&#xff0c;而是用Leader-Follower 模式极大减少了线程唤醒的开销。插入与唤醒、等待与 leader 变更&#xff0c;都通过巧妙的锁和条件变量组合完成。 如果只关注“线程安全的优先队列全局…...

Kafka 消息模式实战:从简单队列到流处理(二)

四、Kafka 流处理实战 4.1 Kafka Streams 简介 Kafka Streams 是 Kafka 提供的流处理库&#xff0c;它为开发者提供了一套简洁而强大的 API&#xff0c;用于构建实时流处理应用程序。Kafka Streams 基于 Kafka 的高吞吐量、分布式和容错特性&#xff0c;能够处理大规模的实时…...

大数据(2) 大数据处理架构Hadoop

一、Hadoop简介 1.定义 Hadoop 是一个开源的分布式计算框架&#xff0c;由 Apache 基金会开发&#xff0c;用于处理海量数据&#xff0c;具备高可靠性、高扩展性和高容错性。它主要由两个核心模块组成&#xff1a; HDFS&#xff08;Hadoop Distributed File System&#xff09…...

【Kotlin】注解反射扩展

文章目录 注解用法反射类引用 扩展扩展函数的作用域成员方法优先级总高于扩展函数 被滥用的扩展函数扩展属性静态扩展 标准库中的扩展函数 使用 T.also 函数交换两个变量sNullOrEmpty | isNullOrBlankwith函数repeat函数 调度方式对扩展函数的影响静态与动态调度扩展函数始终静…...

固定ip和非固定ip的区别是什么?如何固定ip地址

在互联网中&#xff0c;我们常会接触到固定IP和非固定IP的概念。它们究竟有何不同&#xff1f;如何固定IP地址&#xff1f;让我们一起来探究这个问题。 一、固定IP和非固定IP的区别是什么 固定IP&#xff08;静态IP&#xff09;和非固定IP&#xff08;动态IP&#xff09;是两种…...

升级centos 7.9内核到 5.4.x

前面是指南&#xff0c;后面是工作日志。 wget http://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-devel-5.4.225-1.el7.elrepo.x86_64.rpm wget http://mirrors.coreix.net/elrepo-archive-archive/kernel/el7/x86_64/RPMS/kernel-lt-5.4.2…...

Nginx 安全设置配置

1、增加header公共文件 文件地址&#xff1a;/etc/nginx/conf.d/security_headers.conf # XSS防护配置add_header X-XSS-Protection "1; modeblock" always; # 其他安全配置add_header X-Content-Type-Options "nosniff";add_header X-Frame-Options &qu…...

协程的常用阻塞函数

以下是一些常见的阻塞函数示例&#xff1a; 1. **Thread.sleep()** 阻塞当前线程一段时间。 kotlin Thread.sleep(1000) // 阻塞线程 1 秒 2. **InputStream.read()** 从输入流中读取数据时会阻塞&#xff0c;直到有数据可用或流结束。 kotlin val inputStream FileInputStre…...

探索NoSQL注入的奥秘:如何消除MongoDB查询中的前置与后置条件

随着互联网技术的飞速发展&#xff0c;数据库作为信息存储与管理的核心&#xff0c;其安全性问题日益凸显。近年来&#xff0c;NoSQL数据库因其灵活性和高性能逐渐成为许多企业的首选&#xff0c;其中MongoDB以其文档存储和JSON-like查询语言在开发社区中广受欢迎。然而&#x…...

使用矩阵乘法+线段树解决区间历史和问题的一种通用解法

文章目录 前言P8868 [NOIP2022] 比赛CF1824DP9990/2020 ICPC EcFinal G 前言 一般解决普通的区间历史和&#xff0c;只需要定义辅助 c h s − t ⋅ a chs-t\cdot a chs−t⋅a&#xff0c; h s hs hs是历史和&#xff0c; a a a是区间和&#xff0c; t t t是时间戳&#xff0c…...

React Navive初识

文章目录 搭建开发环境安装 Node、homebrew、Watchman安装 Node安装 homebrew安装 watchman 安装 React Native 的命令行工具&#xff08;react-native-cli&#xff09;创建新项目编译并运行 React Native 应用在 ios 模拟器上运行 调试访问 App 内的开发菜单 搭建开发环境 在…...

scss(sass)中 的使用说明

在 SCSS&#xff08;Sass&#xff09;中&#xff0c;& 符号是一个父选择器引用&#xff0c;它代表当前嵌套规则的外层选择器。主要用途如下&#xff1a; 1. 连接伪类/伪元素 scss 复制 下载 .button {background: blue;&:hover { // 相当于 .button:hoverbackgrou…...