c/c++ 汇编码中的.cfi 指令有什么用途?


author: hjjdebug
date: 2025年 06月 12日 星期四 14:24:40 CST
descrip: c/c++ 汇编码中的.cfi 指令有什么用途?


文章目录

  • 1. 几个简写词.
  • 2. 看一个简单的测试代码:
  • 3. 生成汇编代码:
  • 4. 分析.cfi 指令
  • 5. 小结:

1. 几个简写词.

cfi(call frame info) 调用帧信息, 名词. 描述的是调用栈的信息
cfa(call frame address) 调用帧地址, 就是当你执行 call xxx 时,堆栈esp的地址, 这个地址很重要.
它是一个固定的地址,该地址处,执行call时, 首先会存如一个8字节的返回地址.(x86_64)

cfi 作用: 异常时stack 回滚.
当程序崩溃或 C++ 异常抛出时,函数后面的代码就不执行了, 那堆栈如何恢复?
如何找到异常接受代码, 并恢复上一级甚至上上一级堆栈
CFI 信息就保留着各栈帧之间的信息.
eh_frame 节中的 CFI 指令, 记录了各调用栈信息,处理异常代码可据此正确回滚调用栈.

2. 看一个简单的测试代码:

这里不讲回滚细节, 这里之间.cfi 指令是什么, 记录了什么信息.

$ cat main.cpp
#include <stdio.h>
int Add(int i, int j)
{return i+j;
}int main()
{int i=Add(2,3);printf("i:%d\n",i);return 0;
}

3. 生成汇编代码:

g++ -S -o 1.S main.cpp

分析一下Add 函数的汇编代码.

Add(int, int):
.LFB0:.cfi_startprocendbr64pushq	%rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq	%rsp, %rbp.cfi_def_cfa_register 6movl	%edi, -4(%rbp)movl	%esi, -8(%rbp)movl	-4(%rbp), %edxmovl	-8(%rbp), %eaxaddl	%edx, %eaxpopq	%rbp.cfi_def_cfa 7, 8ret.cfi_endproc

4. 分析.cfi 指令

前面已经说过了,cfi 开头的指令都是为了堆栈回滚而存在的,为了形成eh_frame节信息.
.cfi_startproc ;代表栈帧的开始
.cfi_endproc ;代表栈帧的结束

cfi_def_cfa_offset 16
.cfi_def_cfa_offset 16
def 是 define 的简写

定义调用帧地址偏移 为 16
就是说当你调用了pushq %rbp 后, 这个地方的堆栈地址比调用时的堆栈地址偏移了16bytes
这样定义显然是正确的, 因为此时堆栈中保存了8bytes 返回地址, 8bytes ebp值.
cfi 指令就是要跟踪堆栈的变化.

.cfi_offset 6, -16
6号寄存器 值为CFA-16

.cfi_def_cfa_register 6
定义cfa寄存器是6号寄存器
在movq %rsp,%rbp 后调用定义该cfi指令, 说明6号寄存器是%rbp

.cfi_def_cfa 7, 8
7号寄存器 值为CFA+8
在popq %rbp 后调用该指令, 此时堆栈中还有8字节的返回地址,可知.
此处的7号寄存器对应esp
定义cfa 的几号寄存器可能是保留cfi信息的一个必要手段,这里没有具体分析其与eh_frame的对应关系.

5. 小结:

总之, cfi 指令是为了形成eh_frame节而定义的指令,用来跟踪堆栈地址.以备随时可以返回调用帧.
由于函数执行过程中也可能使用堆栈,所以无非就是跟踪定义栈的偏移, 栈的偏移.
具体怎样触发恢复正确的栈帧,这个细节我们没有分析,这应该分析eh_frame 中保留的数据.
这里只需要知道汇编中.cfi 的大体作用就可以了.
由此我们也可以断定,删除所有.cfi指令,不会影响代码的执行. 如果代码没有异常的话.
只有代码出现异常,才会使用到.cfi信息. 这样就解除了对汇编码中.cfi 指令的疑惑.

从另一个角度看,.cfi指令是伪指令,它并不对应cpu的指令代码,但给编译器提供了一些元信息,
就是辅助信息,能够让编译器了解每个frame对应的堆栈信息. 以备不时之需.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/909190.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ArcGIS Pro 3.4 二次开发 - 任务

环境:ArcGIS Pro SDK 3.4 + .NET 8 文章目录 任务1 任务1.1 检索项目中的所有任务项1.2 打开任务文件 - .esriTasks 文件1.3 打开项目任务项1.4 关闭任务项1.5 导出任务项1.6 获取任务信息 - 从 TaskProjectItem1.7 获取任务信息 - 从 .esriTasks 文件1.8 在任务文件中打开特定…

vscode如何修改终端的默认配置

问题困扰&#xff1a; 每次打开都是 powershell, 因为每次要是用 git bash, 所以每次手动切换很麻烦。 要将默认终端设置为 Git Bash&#xff0c;可以通过以下步骤完成。以下是详细的操作方法&#xff1a; 步骤 1&#xff1a;打开终端设置 在 Visual Studio Code 的菜单栏中…

kafka快速入门与知识汇总

​ kafka快速入门与知识汇总 一、前言 kafka是一款消息中间件&#xff0c;可以用于传输消息和日志收集、监控项目状况。与其类似的技术栈有rocketmq、rabbitmq等&#xff0c;但这些技术栈大多应用在一些简单的消息传输平台&#xff0c;而kafka则因其对大量数据的高性能处理在…

设计模式——观察者设计模式(行为型)

摘要 本文详细介绍了观察者设计模式&#xff0c;包括其定义、结构、实现方式、适用场景以及实战示例。通过代码示例展示了如何在Spring框架下实现观察者模式&#xff0c;以及如何通过该模式实现状态变化通知。同时&#xff0c;对比了观察者模式与消息中间件在设计理念、耦合程…

uniapp 页面栈一定深度后,回首页导航到新页面的解决方案

uniapp 页面栈一定深度后&#xff0c;回首页导航到新页面的解决方案 uniapp 页面导航解决方案 在 uniapp 中&#xff0c;要实现先弹出页面栈回到首页&#xff0c;然后再跳转到指定页面。 /*** description 后台选择链接专用跳转*/ interface Link {path: string;name?: stri…

数据结构 散列表 学习 2025年6月12日15:30:48

数据结构 散列表 哈希表(Hash Table): 通过哈希函数将键&#xff08;key&#xff09;映射到存储位置&#xff0c;从而实现快速的插入、删除和查找操作。 哈希表是现代编程中最重要的数据结构之一&#xff0c;几乎所有编程语言都提供了内置实现。 计数 #include <stdio.h&g…

数据结构之LinkedList

系列文章目录 数据结构之ArrayList-CSDN博客 目录 系列文章目录 前言 一、模拟实现链表 1. 遍历链表 2. 插入节点 3. 删除节点 4. 清空链表 二、链表的常见操作 1. 反转链表 2. 返回链表的中间节点 3. 链表倒数第 k 个节点 4. 合并两个有序链表 5. 分割链表 6. 判…

DC3靶机渗透

1. 靶机介绍 主要的内容有 sql 注入漏洞、joomla 框架漏洞、ssh 攻击、shell 反弹、提权 信息收集(ip、端口、目录、指纹信息)--->利用漏洞--->反弹---->提权 2. 信息收集 2.1. 扫描存活 ip 192.168.220.134 2.2. 端口扫描 nmap -T4 -A -p- 192.168.220.134 …

C# 线程交互

一、为什么要进行线程交互 在C#中&#xff0c;线程交互通常涉及到多个线程之间的数据共享和同步。‌. 一、全局变量 在C#中&#xff0c;全局变量是指在程序的任何地方都可以访问的变量。通常&#xff0c;全局变量是在类的外部定义的&#xff0c;或者在所有方法之外定义的。全…

Cursor 编辑器中的 Notepad 功能使用指南

Cursor 编辑器中的 Notepad 功能使用指南 摘要 本指南全面介绍了 Cursor 编辑器中的 Notepad 功能&#xff0c;涵盖其用途、多种访问方式、适用场景以及与其它功能的整合技巧等内容&#xff0c;助力用户高效利用该功能提升工作流程效率。 不同访问方式介绍 功能概述 Curso…

用于评估大语言模型(LLMs)能力的重要基准任务(Benchmark)

基准任务涵盖了 多领域&#xff08;如语言理解、数学、推理、编程、医学等&#xff09;和 多能力维度&#xff08;如事实检索、计算、代码生成、链式推理、多语言处理&#xff09;。常用于模型发布时的对比评测&#xff0c;例如 GPT-4、Claude、Gemini、Mistral 等模型的论文或…

力扣HOT100之技巧:169. 多数元素

这道题如果不考虑空间复杂度和时间复杂度的限制的话很好做&#xff0c;一种思路是通过一次遍历将所有元素的数量记录在一个哈希表中&#xff0c;然后我们直接返回出现次数最多的键即可。另一种思路是直接对数组进行排序&#xff0c;数组中间的值一定是多数元素&#xff0c;因为…

wordpress首页调用指定ID页面内的相册

要在WordPress首页调用ID为2的页面中的相册&#xff0c;你可以使用以下几种方法&#xff1a; 方法一&#xff1a;使用短代码和自定义查询 首先&#xff0c;在你的主题的functions.php文件中添加以下代码&#xff1a; function display_page_gallery($atts) {$atts shortcod…

基于深度学习的异常检测系统:原理、实现与应用

前言 在现代数据驱动的业务环境中&#xff0c;异常检测&#xff08;Anomaly Detection&#xff09;是一个关键任务&#xff0c;它能够帮助企业和组织及时发现数据中的异常行为或事件&#xff0c;从而采取相应的措施。异常检测广泛应用于金融欺诈检测、网络安全、工业设备故障监…

Java基于BS架构的OA流程可视化实战:从工作流引擎到前端交互(附完整源代码+论文框架)

一、引言&#xff1a;BS架构OA系统的流程可视化需求 在企业信息化建设中&#xff0c;基于浏览器/服务器&#xff08;BS&#xff09;架构的OA系统通过流程自动化提升办公效率&#xff0c;而流程可视化是实现流程监控、优化的核心模块。本文基于Java技术栈&#xff0c;结合Activ…

JavaWeb-数据库连接池

目录 1.springboot默认Hikari(追光者)连接池 2.切换为Druid(德鲁伊)连接池 1.springboot默认Hikari(追光者)连接池 2.切换为Druid(德鲁伊)连接池 一般几乎用不到&#xff0c;不需要切换 <!--Druid连接池--> <dependency><groupId>com.alibaba</groupId&…

c# 完成恩尼格玛加密扩展

c# 完成恩尼格玛加密扩展 恩尼格玛扩展为可见字符恩尼格玛的设备原始字符顺序转子的设置反射器的设置连接板的设置 初始数据的设置第一版 C# 代码第二版 C# 代码 总结 恩尼格玛 在之前&#xff0c;我们使用 python 实现了一版恩尼格玛的加密算法&#xff0c;但是这一版&#x…

【Redisson】锁可重入原理

目录 一、基本原理 二、源码解析&#xff1a; &#xff08;2&#xff09;获取锁 &#xff08;1&#xff09;释放锁&#xff1a; 之前给大家介绍过redisson的分布式锁&#xff0c;用redisson来实现比自己手搓简单的分布式锁有很多好处&#xff0c;因为这些可重入、可重试的逻…

BERT 模型微调与传统机器学习的对比

BERT 微调与传统机器学习的区别和联系&#xff1a; 传统机器学习流程 传统机器学习处理文本分类通常包含以下步骤&#xff1a; 特征工程&#xff1a;手动设计特征&#xff08;如 TF-IDF、词袋模型&#xff09;模型训练&#xff1a;使用分类器&#xff08;如 SVM、随机森林、逻…

(12)-Fiddler抓包-Fiddler设置IOS手机抓包

1.简介 Fiddler不但能截获各种浏览器发出的 HTTP 请求&#xff0c;也可以截获各种智能手机发出的HTTP/ HTTPS 请求。 Fiddler 能捕获Android 和 Windows Phone 等设备发出的 HTTP/HTTPS 请求。同理也可以截获iOS设备发出的请求&#xff0c;比如 iPhone、iPad 和 MacBook 等苹…