C++的global data的位置 及PE 文件中的section的内容

本文解析了C语言中变量的存储位置,包括初始化和未初始化的全局变量、局部静态变量的区别,以及常量的存储位置。同时介绍了程序指令与数据分段的原因,包括保护程序指令、提高缓存命中率及利用共享节省内存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 情况一:


int a = 5;

a 在.data section 里面


2. 情况二:


const int a = 5;

a 在 .rdata section里面


扩展:

一般C语言的编译后执行语句都编译成机器代码,保存在.text段。

已初始化的全局变量和局部静态变量都保存在. data段

未初始化的全局变量一般放在一个叫.“bss”的段里。



总体来说,程序源代码被编译以后主要分成两种段:程序指令和程序数据。代码段属于程序指令,而数据段和.bss段属于程序数据。

很多人可能会有疑问:为什么要那么麻烦,把程序的指令和数据的存放分开?混杂地放在一个段里面不是更加简单?其实数据和指令分段的好处有很多。主要有如下几个方面。

程序的指令和数据分开原因

l         一方面是当程序被装载后,数据和指令分别被映射到两个虚存区域。由于数据区域对于进程来说是可读写的,而指令区域对于进程来说是只读的,所以这两个虚存区域的权限可以被分别设置成可读写和只读。这样可以防止程序的指令被有意或无意地改写。

l         另外一方面是对于现代的CPU来说,它们有着极为强大的缓存(Cache)体系。由于缓存在现代的计算机中地位非常重要,所以程序必须尽量提高缓存的命中率。指令区和数据区的分离有利于提高程序的局部性。现代CPU的缓存一般都被设计成数据缓存和指令缓存分离,所以程序的指令和数据被分开存放对CPU的缓存命中率提高有好处。

l         第三个原因,其实也是最重要的原因,就是当系统中运行着多个该程序的副本时,它们的指令都是一样的,所以内存中只须要保存一份改程序的指令部分。对于指令这种只读的区域来说是这样,对于其他的只读数据也一样,比如很多程序里面带有的图标、图片、文本等资源也是属于可以共享的。当然每个副本进程的数据区域是不一样的,它们是进程私有的。不要小看这个共享指令的概念,它在现代的操作系统里面占据了极为重要的地位,特别是在有动态链接的系统中,可以节省大量的内存。比如我们常用的Windows Internet Explorer 7.0运行起来以后,它的总虚存空间为112 844 KB,它的私有部分数据为15 944 KB,即有96 900 KB的空间是共享部分(数据来源见图3-2)。如果系统中运行了数百个进程,可以想象共享的方法来节省大量空间。


### 汇编语言 `global` 指令的使用 #### 定义与作用 `global` 是一种伪指令,在汇编语言中用来声明全局符号,使得这些符号可以在链接阶段被其他文件访问。这意味着当多个源文件组合成一个可执行文件时,标记为 `global` 的函数或变量可以跨模块调用和引用[^1]。 #### 使用场景 通常情况下,如果希望某个特定的过程(子程序)或者数据项能够在不同的源码单元之间共享,则需要将其定义为全局可见。这对于创建库函数或是实现多文件项目非常重要[^2]。 #### 语法说明 在大多数汇编器如 NASM 中,`global` 指令后面跟随的是要公开给外部使用的标签名称。例如: ```nasm section .text global _start ; 将_start 标记为入口点,使其成为公共符号 _start: ; 这里放置启动代码... ``` 上述例子表明 `_start` 被指定为整个项目的起点,并且这个信息会被传递到连接器以便正确设置程序加载后的初始执行位置[^3]。 另一个常见用途是在 C/C++ 和汇编混合编程环境中暴露汇编中的功能供高级语言调用: ```nasm ; 文件名: myfunc.asm extern printf ; 声明外部C函数printf global my_function ; 对外提供my_function接口 section .data msg db "Hello from Assembly!",0 section .text my_function: push rbp ; 函数前序处理 mov rbp, rsp ; lea rdi, [rel msg]; 加载消息字符串地址至rdi参数寄存器 call printf ; 调用C标准库打印函数 pop rbp ; 函数后置恢复 ret ; 返回上级调用者 ``` 这段代码展示了如何通过 `global` 关键字让名为 `my_function` 的过程能够被其它语言编写的部分所识别并调用[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值