软件调试笔记32 - 栈和函数调用: CALL和RET指令

x86汇编CALL与RET指令原理及调用约定详解 在计算机体系结构中,函数调用机制是程序执行流程控制的核心基础。x86架构通过CALL和RET指令对实现了子程序调用的完整生命周期管理,其本质是利用栈结构保存返回地址实现执行流转移。CALL指令在跳转前将返回地址压栈,RET指令则通过弹栈恢复执行位置,这种机制构成了现代编程语言函数调用的底层支撑。理解调用约定(如cdecl、stdcall、fastcall)对参数传递、栈平衡的影响,是进行汇编编程和逆向工程的关键。在安全领域,CALL/RET机制相关的栈溢出漏洞仍是重点防范对象,而尾调用优化等技术则能显著提升 阅读详情

在X86的系统中,这两个指令是专门用来处理函数调用和返回的。下面来看下他们的详细过程。


CALL指令:

CALL是用作函数调用的,它将当前的程序指针EIP寄存器值保存在栈中,然后转移到目标操作数所指定的函数继续执行。根据被调用过程是否在同一个代码段,CALL调用被分为近调用Near Call和远调用Far Call。

近调用过程:

1. 将EIP寄存器的值压入栈中供返回时使用

2. 将被调用的偏移(相对于当前段)加载到EIP寄存器

3. 开始执行被调用过程

远调用过程:

1. 将CS寄存器的当前值压入栈中供返回时使用

2. 将EIP寄存器的当前值压入栈供返回使用

3. 将包含被调用过程的代码段的段选择子加载到CS寄存器中

4.将被调用过程的偏移加载到EIP中

5.开始执行被调用过程


因为大部分进程内的代码都在一个大的4GB段中,所以几乎所有时候使用的都是近调用。


RET指令:





x86汇编中CALL与RET指令的深度解析 在计算机体系结构中,函数调用机制是程序控制流的核心基础。通过栈内存管理实现的过程调用/返回,构成了现代编程语言的执行框架。x86架构下的CALL指令通过压栈返回地址和修改EIP寄存器实现跳转,配合RET指令的弹栈操作完成控制权交还,这种协同工作机制直接影响程序的栈帧结构和执行效率。理解调用约定(如cdecl、stdcall等)对参数传递和栈平衡的影响,是进行底层调试和性能优化的关键。在安全编程领域,返回地址预测和影子栈等现代CPU特性,为防御ROP攻击提供了硬件级支持。这些原理不仅适用于汇编开发,对理解高级 阅读详情

相关推荐

x86汇编CALL与RET指令详解及模块化编程实践

在计算机体系结构中,函数调用机制是程序模块化的核心支撑。x86架构通过CALL和RET指令实现子程序调用,其本质是通过堆栈维护执行上下文。CALL指令将返回地址压栈并跳转,RET则逆向完成返回操作,二者协同保障了程序执行流的正确性。这种机制在嵌入式开发、系统编程等领域尤为重要,涉及堆栈平衡、调用约定等关键技术细节。实际工程中,参数传递方式(堆栈/寄存器)、尾调用优化、跨平台差异处理等都是开发者需要掌握的实践要点。通过理解这些底层原理,可以避免常见的堆栈溢出、返回地址错误等问题,同时提升代码性能和安全性。本文

weixin_42542669的博客 264

x86架构学习之调用指令call

看本文前,作者假设你已经阅读了《x86架构学习之操作模式、内存寻址、特权级》分段特权级调用门操作模式。

qq_26962739的博客 1203

iOS逆向之深入解析函数本质·函数调用栈与相关指令

一、栈与寄存器 ① 栈 栈:是一种具有特殊的访问方式的存储空间(即先进后出 Last In First Out, LIFO): 高地址往低地址存数据(存:高–>低); 栈空间开辟:往低地址开辟(开辟:高–>低)。 ② SP 和 FP 寄存器 SP 寄存器:在任意时刻会保存栈顶的地址; FP 寄存器(也称为 x29 寄存器):属于通用寄存器,但是在某些时刻(例如函数嵌套调用时)可以利用它保存栈底的地址; arm64 开始,取消了 32 位的 LDM、STM、PUSH、POP 指令,取而

╰つ栺尖篴夢ゞ 1万+

x86下的C函数调用惯例

x86 ABI之C函数调用惯例

曾梦想仗剑走天涯 9616

死磕GMSSL通信-java/Netty系列(二)

Netty-tcnative再linux编译比较好编译,但是再window编译,我尝试了各种办法,总是编译失败,所以我采用半自动的方式进行编译,Netty-tcnative会生成临时文件,直接用vs打开,设置openssl的头文件和静态库路径,然后生成静态库,静态库改个名字放到jar包里边,其实自动编译也是这个原理哈哈O(∩_∩)O。直接传输五个证书的路径吗,之前有的是说要转成x509之类的,转来转去的有点麻烦,这个是直接传输证书路径,由底层gmssl去解析,格式必须是pem格式。然而,若项目已依赖于。

qq_36577699的博客 3026

块坐标下降法实战:如何用Python一步步优化无人机通信网络?

本文通过Python实战案例,详细介绍了块坐标下降法在优化无人机通信网络中的应用。文章以最大化网络吞吐量为目标,将复杂的非凸问题拆解为功率分配和轨迹规划两个子问题,并提供了完整的算法实现、代码示例及调参指南,为机器学习工程师解决类似优化问题提供了实用参考。

sat99的博客 975

x86汇编_CALL和RET指令及过程调用嵌套_笔记_20

CALL指令先把将来要返回的地址放入堆栈,再把即将被执行的过程的地址复制到指针寄存器上,当这个过程执行完要返回时,用RET指令将堆栈中存放的原来的地址放回指针寄存器上。 CPU下一步执行哪些内容,是由指针寄存器决定的,这个寄存器存放着地址编码,只要修改这个寄存器CPU就可以到指定位置执行了。32位的指针寄存器叫EIP,16位的叫IP。 ...

Silent_Hunter的博客 3446

PySWMM新手避坑指南:从安装到批量处理INP文件的完整流程(附常见错误解决方案)

本文为PySWMM新手提供从环境搭建到批量处理INP文件的完整避坑指南。详细讲解了虚拟环境配置、库安装方法,并针对“无法打开输入文件”和对象访问错误等高频问题提供解决方案。核心部分展示了如何利用Python脚本实现INP文件的批量运行、结果汇总以及参数自动化修改,显著提升SWMM模型的工作效率。

weixin_29092031的博客 393

汇编语言----X86汇编指令

汇编语言----X86汇编指令 1.汇编指令的构成 2.X86架构CPU中包含的寄存器 3.常见的x86汇编指令 (1)算数运算 (2)逻辑运算 (3)其他 4.AT&T格式 5.选择语句(分支结构) 6.循环语句 (1)条件转移指令实现循环 (2)loop指令实现循环 7.函数调用的机器级指令 如何访问栈帧中的数据 函数调用栈在内存的位置: 访问栈帧数据:push、pop指令: 函数调用时切换栈帧: 恢复esp与ebp的值: 执行ret: 栈帧内可能包含哪些内容 如何

weixin_69884785的博客 5574

yolov8x-p2 实现 tensorrt 推理

yolov8x-p2, tensorrt 实现.

J。 2273

华为OD机试 - 停车场费用统计 - HashSet(Python/JS/C/C++ 双机位C卷 100分)

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。停车场统计当日总收费,包月的车不统计,不包月的车半个小时收一块钱,不满半小时不收费,如果超过半小时,零头不满半小时按半小时算,每天11:30-13:30时间段不收费,如果一辆车停车时间超过8小时后不收费。现提供停车场进出车辆的统计信息,需要你来计

学Java,找哪吒 238

x86架构常见寄存器及指令详解

详解寄存器及指令

m0_55906008的博客 3181

Qt C++ + Qt 3D 的数字孪生工厂

以下是一个基于 **Qt C++ + Qt 3D** 的数字孪生工厂完整源码示例,集成了 **Qt 3D** 产线建模和 **WebSocket** 实时数据交互。ui->qualifiedProductsLabel->setText(QString("合格产品: %1").arg(data.qualifiedProducts));ui->totalProductsLabel->setText(QString("总产量: %1").arg(data.totalProducts));

寒寒豆豆软件公司的博客 149

Push, Pop, call, leave 和 Ret 指令图解

指令图解:最近在研究如何在程序crash定位出错函数,补充的计算机系统基础知识。此篇主要是介绍IA32中重要的几个汇编指令(以AT&T为例),详情请参考《深入计算机系统2》第三章第三节。PUSH 和 POP指令的汇编格式:PUSH SRC ;POP DST指令的基本功能:PUSH指令在程序中常用来暂存某些数据,而POP指令又可将这些数据恢复。PUSH 等价于:subl $4, %espmo......

自学C++,会写HelloWorld 4277

ardupilot开发 --- 避障篇

适配ardupilot的雷达避障功能开发,使用低成本雷达思岚科技系列雷达,配置简单,灵敏度高,障碍物检测范围不低于30m。

记录老板的每次pua,分享领导每天的毒鸡汤... 4301

如何使用 Conda 安装 Qiskit(详细教程)

本文介绍了使用conda安装Qiskit量子计算工具包的完整流程。首先创建Python 3.10的conda虚拟环境(qiskit_env),然后安装Qiskit核心包及可视化组件(注意Mac用户的安装命令差异)。接着注册IPython内核并测试环境,通过量子电路创建与可视化演示验证安装成功。该教程为量子计算开发提供了简洁的环境配置指南,适合研究者和开发者快速搭建Qiskit开发环境。

猿小白的博客 565

CALL与 RET指令及C#抽象函数和虚函数执行过程解析

本文深入解析了CALL/RET指令和C#虚函数调用的底层机制。CALL指令执行时会将返回地址压栈并跳转目标函数,RET指令则弹出返回地址恢复执行流程。在C#中,虚函数和抽象函数通过虚表(vtable)实现多态,每个对象包含虚表指针(vptr),调用时通过间接寻址访问实际函数地址。文章详细剖析了虚表生成原理、调用指令的底层逻辑,并通过反汇编示例展示了实际执行过程,同时对比了不同语言的实现差异,为理解函数调用和多态机制提供了底层视角。

hpx666的博客 1178

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

x86汇编中CALL与RET指令的底层原理与应用

在计算机体系结构中,函数调用是程序控制流的核心机制。x86架构通过CALL和RET指令对实现子程序调用,其本质是通过栈内存保存返回地址并切换指令指针。从技术实现看,CALL指令完成返回地址压栈和EIP寄存器更新,而RET指令则逆向操作恢复调用现场。这种机制直接影响程序的栈平衡和内存安全,特别是在递归调用和动态链接库等场景中尤为关键。现代CPU通过Return Stack Buffer等特性优化调用性能,同时Intel CET等安全扩展为返回地址提供硬件级保护。理解这些底层原理对于逆向工程、性能优化和安全编程

weixin_28740299的博客 268

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

x86汇编CALL与RET指令原理与应用详解

在计算机体系结构中,函数调用机制是程序模块化的核心实现方式。x86架构通过CALL和RET指令对实现子程序调用,其本质是借助栈结构完成返回地址保存与恢复。CALL指令执行时会将EIP寄存器值压栈并跳转,RET指令则逆向操作实现流程返回,这种机制构成了现代编程语言函数调用的底层基础。在性能优化方面,寄存器间接调用比内存间接调用快3-5个时钟周期,而带立即数返回的RET指令能高效清理栈参数。这些特性在系统编程、编译器实现、安全防护(如对抗ROP攻击)等领域有广泛应用,特别是在实现协程切换、状态机等高级特性时,对

weixin_32956805的博客 270

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Windows逆向工程入门之栈指令与核心机制深度解析

在64位程序中,某些API(如Windows API)要求栈按16字节对齐。:固定指向当前函数的栈帧基址,用于定位参数和局部变量(尤其在未优化代码中常见)。:参数从右向左压栈,被调用者清理栈(Windows API常用)。:部分参数通过寄存器传递(如ECX、EDX),剩余参数压栈。| 旧的EBP | ← EBP当前指向。| 参数n | ← EBP + 8。| 局部变量2 | ← EBP - 8。:参数从右向左压栈,调用者清理栈(常见于C语言)。

0xCC说逆向 1903

x86汇编CALL与RET指令详解及优化实践

在计算机体系结构中,函数调用是程序执行流控制的基础机制。x86架构通过CALL和RET指令对实现子程序调用,其核心原理涉及栈操作与寄存器管理。CALL指令将返回地址压栈并跳转,RET则逆向恢复执行流。现代CPU通过返回地址预测(RSB)和投机执行优化调用性能,但这也引入了Spectre等安全漏洞风险。在工程实践中,调用约定(cdecl/stdcall)的选择、栈平衡维护以及尾调用优化等技术直接影响程序性能和稳定性。这些机制在操作系统内核开发、嵌入式系统及高性能计算等领域有广泛应用,理解其底层实现有助于调试栈

weixin_26869081的博客 320

【C语言编译】C语言的函数调用的过程

C语言的函数调用的过程

LeonJin的博客 6158

运行时堆栈及函数调用中的部分相关指令

运行时堆栈 运行时堆栈是内存数组,CPU用ESP(堆栈指针寄存器)对其进行直接管理,32位模式下,ESP寄存器存放的是堆栈中某个位置的32位偏移量.ESP基本上不会直接被程序员控制,它是用CALL,RET,PUSH和POP等指令间接进行修改. 运行时堆栈工作于系统层,处理子程序调用. ESP总是指向压入到栈顶的最后一个数值。 如下图所示:ESP中保存的是刚压入堆栈数值(00000001)的偏移量。...

qq_43313035 1299

函数调用栈详解

前几天忙里偷闲重做6.828,发现在lab 1 exercise 11卡住了,才发现之前觉得很熟了的函数调用栈已经因为太久没接触忘了,一年没有用过这些东西了。 看了几篇博客,发现理解还是不够深入,只能自己再手动测一下试一试了。 写了一个C文件,叫temp.c #include <stdio.h> int double_add_int(int a, int b) { int c = a; int d = b; int e = a + b + c + d; retu

辣鸡的博客 1306

汇编语言call指令避坑指南:段内转移vs段间转移的7个关键区别

本文深入解析汇编语言中call指令在段内转移与段间转移的7个核心区别,涵盖栈空间消耗、指令编码、调试识别、栈平衡陷阱等关键点。重点剖析了call far ptr与call word ptr/dword ptr的差异及其对应的ret/retf指令匹配,帮助开发者避免因调用类型混淆导致的栈破坏和程序崩溃,提升底层代码编写与调试能力。

linux的博客 844
上一篇: 软件调试笔记31 - 栈和函数调用:栈的创建
下一篇: 软件调试笔记33 - 栈和函数调用: 局部变量和栈桢
imJaron
博客等级 码龄11年 121粉丝 286原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值