C专家编程 —— 运行时数据结构

news2024/12/29 8:42:18

文章目录

    • 代码和数据
      • 代码与可执行文件中对应的位置
      • 可执行文件中的段在内存中的布局
      • 加入动态链接库的内存空间布局
      • 堆栈段的作用
      • 过程活动记录
        • 函数调用过程记录举例
      • static和auto关键字
    • 汇编嵌入C代码

代码和数据

代码和数据的区别可以理解为编译时和运行时的分界线。
代码:即C语言编写的
编译器的工作绝大部分是翻译代码
数据:运行时的可执行文件中保存的二进制数据。

目标文件和可执行文件由几种不同的格式,一般称作ELF格式,在UNIX中为a.out格式。
所有不同格式都有一个不同概念,那就是段segment。
段对Unix目标文件来说:他是二进制文件中的简单的区域划分,内容块。里面保存了某种特定类型的相关所有信息。
section:是ELF文件中的最小组织单位。一个段一般包含几个section。

而段在Intel x86模型中,表示一种设计结果,设计地址空间并非一个整体而是分成一些64K大小的区域,称为段。

当对一个可执行文件执行size命令时,比如size a.out就会打印出该文件的3个段,text, data, bss段的大小。

代码与可执行文件中对应的位置

在这里插入图片描述

BSS段:未初始化的全局和静态变量
data段:初始化后的全局和静态变量
text段:指令

可执行文件中的段在内存中的布局

下图我们可以看到可执行文件段对应到程序内存中的段。
在可执行文件中,段是一块数据内容。
在进程内存中,段是一片连续的虚拟地址。
在这里插入图片描述

text文本段包含的是代码转换成的二进制指令,他直接被拷贝到内存中
数据段包含初始化的全局和静态变量,一般情况下这个段是最大段。
BSS段是未初始化的数据。
堆栈段:存储局部变量,临时数据以及函数形参。
堆:用于动态分配内存。

虚拟地址的最低地址并未被映射,比如0x000001。他位于进程的地址空间但是并未赋予物理地址,对这里的引用都是非法的。一般他是从地址0开始的几K个byte。用于捕捉使用空指针和小整型值指针应用内存情况。

加入动态链接库的内存空间布局

在这里插入图片描述

堆栈段的作用

堆栈段包含一种单一的数据结构:堆栈。
程序运行时系统维护一个指针,通常位于寄存器中,称为sp,用于提示堆栈当前的顶部位置。
堆栈主要由以下3个用途:

  1. 堆栈为函数内部声明的局部变量提供存储空间。
  2. 进行函数调用时,堆栈存储于此有关维护性信息,叫做过程活动记录。他包含函数的调用地址,也就是调用函数结束后跳回的地方,以及一些寄存器的值。
  3. 堆栈也可以被用作暂时存储区。比如通过alloca函数分配的内存就存储在堆栈中。所以alloca申请的函数无需释放

在绝大多数处理器中,堆栈是向下增长,也就是朝着低地址方向生长。

过程活动记录

C语言 自动提供的服务之一是跟踪调用链——哪些函数调用了哪些函数,以及函数return后返回到何处等。
解决这个问题使用的机制就是堆栈中的过程活动记录。
每个函数调用时都会产生一个过程活动记录。他是一种数据结构,用于支持过程调用。
在这里插入图片描述
C 语言不允许函数内部嵌套定义函数。

函数调用过程记录举例

void a (int) {
	if(i > 0)
		a(--i);
	else
		printf("i is zero");
	return;
}
int main() {
	a(1);
}

程序控制流如下
在这里插入图片描述
其中,prev frame表示前一个活动记录。比如函数a调用时,prev frame就指向前一个main函数的记录的返回值地址。
当一个函数调用另一个函数时,堆栈的状态就会如图所示,堆栈向下生长。
当函数执行完,会通过prev frame指针找到上一条记录的返回值地址中。

通过这个过程我们可以看到堆栈调用函数是后进先出的,一个函数内部调用另一个函数。

可以参考这里
C语言过程活动记录

static和auto关键字

我们看下面这个例子

char* func() {
	char ch_arr[] = "apple";
	return ch_arr;
}

当进入该函数时,ch_arr在栈中分配。函数结束时,变量就会被释放,他的资源会被回收。
这时将这个指针返回,我们再使用的时候,就会有问题,因为他已经被释放,所以他引用的资源可能无效也可能是其他值。这个结果是可怕的。

如果我们想返回一个指针在函数内部定义的,我们可以把这个变量声明为static。
这样就能保证该变量被保存在data段中而不是堆栈中,该变量的生命周期就和程序一样长。当函数退出时,该变量仍然可以保持。

存储变量auto在实际中完全用不到,他是默认给局部变量的。

汇编嵌入C代码

可以把汇编代码嵌入到C代码中。
这通常只适用于深入操作系统核心且依赖机器的任务。
在这里插入图片描述编译器并不会对内联汇编代码做多少检查,所以很容易创建出崩溃的程序。
但是这是一种很好的学习机器指令集的方法。

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

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

相关文章

guacamole 纯web rdp预研:相关JAVA基础

文章目录 guacamole 纯web rdp预研:相关JAVA基础1. pom.xml2 scm标签3 application/octet-stream4. tomcat webapps下war包5 maven-assembly-plugin maven assembly插件介绍什么是assembly? 6. Mavenz中的source插件的使用和注意事项。7. Maven私库安装与配置8. 配置…

深度学习之目标检测R-CNN模型算法流程详解说明(超详细理论篇)

1.R-CNN论文背景 2. R-CNN算法流程 3. R-CNN创新点 一、R-CNN论文背景 论文网址https://openaccess.thecvf.com/content_cvpr_2014/papers/Girshick_Rich_Feature_Hierarchies_2014_CVPR_paper.pdf   RCNN(Region-based Convolutional Neural Networks&#xff…

牛客网基础语法81~90题

牛客网基础语法81~90题😘😘😘 💫前言:今天是咱们第九期刷牛客网上的题目。 💫目标:可以循环嵌套使用熟练,数组的变问题,对数学知识掌握更加清晰。 💫鸡汤&…

Matplotlib---热力图

1. 热力图 imshow 是 Matplotlib 库中一个函数,主要用于在 Python 中显示图像。它的完整参数列表如下: matplotlib.pyplot.imshow(X, cmapNone, normNone, aspectNone, interpolationNone, alphaNone, vminNone, vmaxNone, originNone, extentNone, sh…

管理类联考——逻辑——知识篇——论证推理——三、假设——haimian

假设 考点分析 假设 年度 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023题量1132111 主要问法 上述论述是基于以下哪项假设?基于以下哪项假设能使上述推理成立?上述论证依赖于以下哪项假设?得到这一结论的前提条件是? 解题思路 阅读问题,确…

【TCP/IP】多播 - 定义、原理及编程实现(TTL、多播组、收发信息)

目录 多播 多播的原理 多播的数据传输时的特点 TTL 的概念 TTL 和 多播组的配置方法 多播的编程与实现 发送者 接收者 多播 多播是一种介于单播和广播通信之间的技术方式,可以将发送者所需要发送的数据包分别发送给分散在不同子网中的一组接收者。 多播的原…

分布式软件架构——事务ACID

事务概念 事务处理几乎是每一个信息系统中都会涉及到的问题,它存在的意义就是保证系统中的数据是正确的,不同数据间不会产生矛盾,也就是保证数据状态的一致性(Consistency) 关于一致性,我们重点关注的是数…

ElasticSearch-安装Head可视化插件

安装Head可视化插件 首先需要依赖node.js和npm环境 1 安装node.js 官方下载地址:http://nodejs.cn/download/ 下载LTS版本(长期稳定版本) 安装可以更改安装路径,其余的都是选择 下一步傻瓜是安装 安装成功后如下 命令测试 node -v 查看node的版本 n…

理解redis的多线程和IO多路复用

参考资料 https://blog.csdn.net/TZ845195485/article/details/119745735 Redis单线程和多线程问题的背景 Redis里程碑版本迭代 Redis的单线程 主要是指Redis的网络IO和键值对读写是由一个线程来完成的,Redis在处理客户端的请求时包括获取(socket读&a…

「实验记录」MIT 6.824 KVRaft Lab3A Without Log Compaction

#Lab3A - KVRaft without log compaction I. SourceII. My CodeIII. MotivationIV. SolutionS1 - client请求S2 - server回应 V. Result I. Source MIT-6.824 2020 课程官网Lab3: KVRaft 实验主页simviso 精品付费翻译 MIT 6.824 课程Paper - Raft extended version II. My C…

Python顺序结果、选择结构、循环结构(超详细讲解+多段代码案例)

我本微末凡尘,可也心向天空 文章目录 一、顺序结构 二、选择结构 1.if----elif----else语句 2.条件表达式 三、循环结构 1.range函数 2.while 循环 3. for----in 循环 四、continue、break在循环中的使用 大家好,我是纪宁 今天要介绍的是python…

fatal error: ‘type_traits‘ file not found错误解决

错误如下 In file included from ../test_opencv_qt/main.cpp:1: In file included from ../../Qt/6.5.1/android_x86_64/include/QtGui/QGuiApplication:1: In file included from ../../Qt/6.5.1/android_x86_64/include/QtGui/qguiapplication.h:7: In file included from .…

Nginx 限流算法大揭秘

博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌ Java知识图谱点击链接:体系化学习Java(Java面试专题) 💕💕 感兴趣的同学可以收…

01 | 一条 SQL 查询语句是如何执行的?

以下内容出自 《MySQL 实战 45 讲》 一条 SQL 查询语句是如何执行的? 下面是 MySQL 的基本架构示意图,从中可以清楚地看到 SQL 语句在 MySQL 的各个功能模块中的执行过程。 大体来说,MySQL 可以分为 Server 层和存储引擎层两部分。 Server …

leetcode188. 买卖股票的最佳时机 IV.动态规划-java

买卖股票的最佳时机 IV leetcode188. 买卖股票的最佳时机 IV题目描述 动态规划代码演示 动态规划专题 leetcode188. 买卖股票的最佳时机 IV 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/best-time-to-buy-and-sell-st…

DatenLord前沿技术分享 No.28

达坦科技专注于打造新一代开源跨云存储平台DatenLord,通过软硬件深度融合的方式打通云云壁垒,致力于解决多云架构、多数据中心场景下异构存储、数据统一管理需求等问题,以满足不同行业客户对海量数据跨云、跨数据中心高性能访问的需求。在本周…

Reentrantreadwritelock应用和原理

目录 一、介绍 二、应用 三、原理 一、介绍 当读操作远远高于写操作时,这时候使用读写锁让读-读可以并发,提高性能 类似于数据库中的共享锁 select...from...lock in share mode 提供一个数据容器类内部分别使用读锁保护数据的read()方法&#x…

Android 9-SystemUI:(1)启动流程

具体分析(以下代码示例,讲解,都是通过,Android9代码来举例) SystemUI,其实是可以看作是一个系统级的服务,也就是SystemUIService, SystemUI的服务启动,要从SystemServer.run()方法入手 main 方法里启动了…

JavaWeb小记—响应对象response

目录 响应对象response的原理图 response——响应对象 响应文本数据 响应字节数据 验证码案例 响应状态码 1.http状态返回代码 1xx(临时响应) 2.http状态返回代码 2xx (成功) 3.http状态返回代码 3xx (重定向…

2023.6.12-6.18 AI行业周刊(第151期):AI创业项目交付部署,困难和机遇并存

这段时间,工作上项目上的事情,开始进入了一个快车道,很多项目开始并行。所以每天白天的时候,被各种事情填充的很满。 加入华勤后从0到1组建的团队,其实本身也是创业属性,从市场->售前->算法->视频…