首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么在用GCC编译的时候,.o文件似乎有一个大小为0的.bss段?

在使用GCC编译时,.o文件中出现大小为0的.bss段是因为GCC在编译过程中会为未初始化的全局变量和静态变量分配内存空间,但不会为其赋初值。这些未初始化的变量会被放置在.bss段中。

.bss段是一种特殊的数据段,它在可执行文件中占据一定的空间,但在磁盘上不占用实际空间。当程序加载到内存中时,操作系统会为.bss段分配实际的内存空间,并将其初始化为0。

.bss段的存在有以下几个优势:

  1. 节省磁盘空间:由于.bss段在磁盘上不占用实际空间,可以减小可执行文件的大小。
  2. 加载速度快:由于.bss段的数据在内存中是连续的,并且已经初始化为0,加载时无需读取磁盘数据,加快了程序的启动速度。
  3. 简化编程:开发人员无需手动初始化未初始化的全局变量和静态变量,编译器会自动处理。

.bss段的应用场景包括但不限于:

  1. 全局变量和静态变量:未初始化的全局变量和静态变量会被放置在.bss段中。
  2. 静态数组和结构体:未初始化的静态数组和结构体也会被放置在.bss段中。

腾讯云相关产品中,与GCC编译器相关的服务包括云服务器(ECS)、容器服务(TKE)和函数计算(SCF)等。这些产品可以提供云端的计算资源和环境,支持开发人员使用GCC编译器进行软件开发和部署。

更多关于腾讯云产品的信息,请访问腾讯云官方网站:https://cloud.tencent.com/

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

深入理解编译、链接和运行(obj文件组成格式分析,可执行文件组成格式分析)

编译和汇编,最终生成可执行文件,其中在windows下生成 .obj文件,在linux下生成 .o文件,学名叫做二进制可重定位文件 (1)预编译gcc -E *.c -o *.i 预编译要干的事情...(2)编译gcc -S *.i -o *.s 词法分析、语法分析和语义分析、代码优化、编译、汇总所有的所有的符号 (3)汇编:gcc -c *.s -o *.o 将汇编指令转换为特定平台下机器语言...答:由于.bss中都是0,所以不需要记录。只需要记录其大小即可,所以通过表即可找到。...(2.2)分析测试代码,得出由六个变量位于.bss,但实际上在.bss大小只有20个字节即只记录了5个变量,那么还有一个变量为什么不记录,它在哪里? 答:这里涉及到强弱符号,我会单独写出来。...浅显可以这样理解,由于全局变量gdata3是一个弱符号,而未经链接。并不知道是否强符号存在,所以在.bss中并为记录。

1.7K30

快速上手和使用makefile

想学习一样东西,最好先问个为什么要这样,这样学起来才有目标。上大学时,老师讲课总是告诉我们必须这样那样,很少讲这门课是干什么什么意义,什么用。...为什么要用makefile?简单说makefile就是编译程序用,因为用makefile效率高。代码小倒没什么,像linux那样几千万行代码,一个一个文件去敲命令行可敲到什么时候。...还有就是调试时,如果只改动了一个文件,就要全部编译一遍,那该是多慢。因此,makefile出现了。改动或者编写完代码,只需要简单make一下就行了。makefile原理是什么?...链接器并不管函数所在文件,只管函数中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以...GCC开发 stm32例子,没有用启动文件start.s 如我以下几个文件:isr.c,uart_helloworld.c,链接脚本文件stm32f103VET6.ld 文件内容:isr.c,

1.4K20

程序编译、链接、装载与运行

gcc可以使用如下命令对C语言进行预编译并且把预编译结果输出到hello.i文件gcc -E hello.c -o hello.i 编译 编译就是对预处理之后文件进行词法分析、语法分析、语义分析并优化后生成相应汇编文件...我们使用如下命令来编译预处理之后文件 gcc -S hello.i -o hello.s 或者我们也可以把预处理和编译合为一步 gcc -S hello.c -o hello.s 汇编 汇编目的是把汇编代码转化为机器指令...我们可以使用如下命令实现汇编 gcc -c hello.s -o hello.o 或者我们也可以直接把源代码文件编译为目标文件 gcc -c hello.c -o hello.o 汇编操作所生成文件叫做目标文件...:虚拟地址,因为目标文件尚未执行链接操作,所以虚拟地址0 LMA:被加载地址,同上原因为0 File off:在ELF文件偏移地址 CONTENTS:表示此段存在于ELF文件中 … 我们重点关注...栈一个函数调用维护了其所需要一些信息,每个函数所维护信息部分叫做栈帧(Stack Frame),栈被分割很多个栈帧。

1.3K10

9_重定位

零初始化(.bss):存放没有初始值或初始值0全局类变量 注释(.comment):存放注释 ​ 注意: bss和注释不保存在bin/elf文件中 注释里面的机器码是用来表示文字 ​...9.3.2 汇编重定位data ​ 下面我们将通过一个实例来说明为什么要重定位data以及如何通过汇编重定位data。 ​...所以我们将.data重定位后地址设置0x900000。 9.3.2.4 步骤2:修改链接脚本 ​ 创建一个变量用来存储.data起始加载地址。...使用取址符号(&)得到该变量值,例如:int * p = & _ start; //plds文件中_start值 ​ 为什么在汇编文件中可以直接使用链接脚本中变量,而在C函数中需要加上取址符号呢...原因:C函数中定义一个全局变量int g_i = 10;,程序中必然4字节空间留出来给这个变量g_i,然而链接脚本中变量并像全局变量一样都保存在.bin文件中。

94510

【嵌入式开发】ARM 异常向量表 ( 异常概念 | 异常处理流程 | 异常向量 | 汇编代码 )

_irq 标号, .word 表示该标号存储是 32 位值, 这个值大小就是 irq 地址; 8.分支指令 : 当异常发生时候, 需要跳转到对应异常处理指令中; ( 1 ) 分支指令语法格式...代码 ENTRY(_start) ; 3.设置代码 : 使用 .text : 设置代码; 4.设置数据 : 使用 .data : 设置数据; 5.设置 BSS : 使用 .bss :...Makefile 编译脚本 ---- makefile 文件编写 : 1.通用规则 ( 汇编文件编译规则 ) : 汇编文件 编译 成同名 .o 文件, 文件名称相同, 后缀不同, %.o : %.S...: C 代码编译成同名 .o 文件, %.o : %.c , 产生过程是 arm-linux-gcc -g -c $^ ; 3.设置最终目标 : 使用 all: 设置最终编译目标; ( 1...o : %.S #通用规则, 如 start.o 是由 start.S 编译, -c 是只编译不链接 arm-linux-gcc -g -c $^ %.o : %.c #通用规则

3.5K10

浅析C++内存布局

(注意:初始化为0全局变量还是被保存在BSS),static声明变量也存储在数据。 .bss bss存储没有初值全局变量或默认为0全局变量,属于静态内存分配。 ...总结 1、执行文件中包含了text、rodata、data内容,不包含bss内容(一堆0放入执行文件没有意义) 2、堆和栈内存增长方向是相反:栈是从高地址向低地址生长,堆是从低地址向高地址生长...一个空类对象大小是1,为什么不是0? 类A明明是空类,它大小应该为0为什么编译器输出结果1呢?...二进制可执行文件执行流程 可执行文件生成过程 预处理:进行头文件和宏定义替换 编译:由编译器把高级语言代码编译为汇编代码 汇编:由汇编器把汇编代码翻译成二进制代码,也即是.o文件 连接:由连接器把多个...子进程通过execve系统调用调用加载器,加载器删除现有的虚拟内存,创建新代码段数据堆栈,新堆栈被初始化为0,通过将虚拟地址空间页映射到可执行文件页面大小chunk,新代码和数据被初始化为可执行文件内容

1.1K40

认识目标文件结构

我们可以使用编译命令gcc -m32 -c test.c -o test32.o生成32位目标文件。 (3)数据存储方式(Data),小端字节序。...这其实和不同语言与编译实现有关,有些编译器会将全局未初始化变量放在.bss,有些则不放,只是预留一个未定义全局变量符号,等到最终链接成可执行文件时候再在.bss分配空间。...为什么编译器把未初始化全局变量标记为一个COMMON符号,而不直接把它当作未初始化局部静态变量,其在.bss分配空间呢?...(2)链接时,读取了所有目标文件,确定了任意一个弱符号大小。这时才在最终输出文件.BSS其分配空间。 (3)总体看来,未初始化全局变量最终还是被放在.BSS。...对于 test.o13个 Elf64_Shdr 元素,第一个无效描述符,它类型 NULL,所以 test.o 共有12个有效

1.1K30

GCC开发STM32入门二

然后链接脚本文件告知链接器,把所有目标文件相应连接到一起,并把目标文件“变量地址”“函数地址”重定位至正确地址空间; 编写前需要知道C程序编译典型内存布局 ,单片机启动流程以及链接脚本文件作用和编写等知识...向量表中内容是32位地址,这些地址是中断异常服务程序入口地址,其中向量表一个单元, 即地址0x0000 0004处存放是复位向量,也就是说Cortex-m3复位后,执行该向量(可理解函数指针...5、链接 gcc编译C源程序文件后,得到目标文件,目标文件需要连接得到最后可执行文件,程序才能执行。...一般来说,目标文件包含 .text: 可执行代码 .rodata: 只读数据,对应程序中常量 .data: 初始化全局变量 .bss: 未初始化全局变量 连接器所作工作简单讲就是...= 0; nCount--); } //编译本工程makefile文件 BINARY = main PREFIX = arm-elf CC = $(PREFIX)-gcc LD = $(

1.8K20

Linux pwn入门学习到放弃

FORTIFY_SOURCE设为1,并且将编译器设置优化1(gcc -O1),以及出现上述情形,那么程序编译时就会进行检查但又不会改变程序功能 开启命令如下: gcc -o test test.c...特别像某些头文件 #include )_FORTIFY_SOURCE设为1,并且将编译器设置优化1(gcc -O1),以及出现上述情形,那么程序编译时就会进行检查但又不会改变程序功能...看编译二进制汇编我们可以看到gcc生成了一些附加代码,通过对数组大小判断替换strcpy, memcpy, memset等函数名,达到防止缓冲区溢出作用。...这部分区域大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码可写,即允许修改程序。在代码中,也有可能包含一些只读常数变量,例如字符串常量等。...对以后分析真实利用场景漏洞很大帮助。利用脚本尽量做通用,考虑多个平台。那么分析利用了,对于漏洞挖掘这方面又是新一个课题,对于这方面的探索将另外写文章分析。

3.5K10

变量访问被ARM架构安排明明白白

作为过来人,我发现很多程序猿新手,在编写代码时候,特别喜欢定义很多独立全局变量,而不是把这些变量封装到一个结构体中,主要原因是图方便,但是要知道,这其实是一个不好习惯,而且会降低整体代码性能。...以Cortex A9架构前提,下面一口君详细给你解释为什么使用结构体效率会更高一些。 一、全局变量代码反汇编 1....在C源代码中,文字池分配是由编译器在编译时自行安排,在进行汇编程序设计时,开发者可以自己进行文字池分配,如果开发者没有进行文字池安排,那么汇编器就会代劳。 「bss占用4个字节」 ?...通过当前pc值40008018偏移32个字节,找到xx变量链接地址40008038,然后取出其内容40008044存放在r3中,该值就是xx在bss地址 15....由上图可知: 结构体变量peng位于bss,地址是4000802c 访问结构体成员也需要利用pc找到结构体变量peng对应文字池中地址40008028,然后间接找到结构体变量peng地址4000802c

84930

Arm放弃了自家汇编语法?改投GNU了?

将定义符开始代码编译到数据,初始化数据 .bss .bss {subsection} 将变量存放到.bss,未初始化数据 .align .align{alignment}{,fill}...不含lds文件编译 假设我们以下代码,包括1个main.c文件,1个start.s文件:start.s .global _start _start: @汇编入口 ldr sp,=0x41000000...,缩小了文件尺寸, clean目标 clean目标的执行语句,删除编译产生临时文件 【补充】 gcc代码优化级别,在 makefile 文件编译命令 4级 O0 -- O3 数字越大,优化程度越高...依赖lds文件编译 实际工程文件复杂程度远比我们这个要复杂多,尤其Linux内核几万个文件分布及其复杂,所以这就需要我们借助lds文件来定义内存分布。 ?...(4);表示下面的4字节对齐 连接器每读完一个section描述后, 将定位器符号值增加该section大小

2.1K30

Linux 程序编译过程来龙去脉

以Hello World例: 如果使用命令“gcc hello.c -o hello”则会使用动态库进行链接,生成ELF可执行文件大小(使用Binutilssize命令查看)和链接动态库(使用...Binutilsldd命令查看)如下所示: $ gcc hello.c -o hello $ size hello //使用size查看大小 text data bss...)如下所示: $ gcc -static hello.c -o hello $ size hello //使用size查看大小 text data bss dec...not a dynamic executable //说明没有链接动态库 链接器链接后生成最终文件ELF格式可执行文件一个ELF可执行文件通常被链接不同,常见譬如.text、.data、...一个典型ELF文件包含下面几个: .text:已编译程序指令代码。 .rodata:ro代表read only,即只读数据(譬如常数const)。

2.9K30

Linux 程序编译过程详解

以Hello World例: 如果使用命令“gcc hello.c -o hello”则会使用动态库进行链接,生成ELF可执行文件大小(使用Binutilssize命令查看)和链接动态库(使用...Binutilsldd命令查看)如下所示: $ gcc hello.c -o hello $ size hello //使用size查看大小 text data bss...)如下所示: $ gcc -static hello.c -o hello $ size hello //使用size查看大小 text data bss dec...not a dynamic executable //说明没有链接动态库 链接器链接后生成最终文件ELF格式可执行文件一个ELF可执行文件通常被链接不同,常见譬如.text、.data、...一个典型ELF文件包含下面几个: .text:已编译程序指令代码。 .rodata:ro代表read only,即只读数据(譬如常数const)。

1.8K30

【嵌入式开发】 嵌入式开发工具简介 (裸板调试示例 | 交叉工具链 | Makefile | 链接器脚本 | eclipse JLink 调试环境)

.o $(obj) gcc app2.o $(obj) -o app2 (2) 系统定义变量 系统定义变量 :  -- $^ : 代表依赖文件; -- $@ : 代表目标; -- $< : 代表第一个依赖文件...链接器脚本示例 可执行程序组成 : 代码, 数据, bss ; 链接器脚本就是配置这些信息; 简单链接器脚本示例 :  -- 代码 : .text 表示代码, * 表示所有文件, *(.text...) 表示所有文件代码; -- 数据 : .data 表示数据, * 表示所有文件, *(.data) 表示所有文件数据; -- bss : .bss 表示 bss , * 表示所有文件,...*(.bss) 表示所有文件 bss ; SECTIONS{ .text : { *(.text) } .data : { *(.data) } .bss : { *(.....data : { *(.data) } .bss : { *(.bss) } } -- 反编译编译 elf 文件 : "00000000 :" 表示从 0

1.8K20

Linux 程序编译过程详解

使用gcc进行汇编命令如下:$ gcc -c hello.s -o hello.o // 将编译生成hello.s文件汇编生成目标文件hello.o /...以Hello World例:如果使用命令“gcc hello.c -o hello”则会使用动态库进行链接,生成ELF可执行文件大小(使用Binutilssize命令查看)和链接动态库(使用Binutils...ldd命令查看)如下所示:$ gcc hello.c -o hello$ size hello //使用size查看大小 text data bss dec hex...//说明没有链接动态库链接器链接后生成最终文件ELF格式可执行文件一个ELF可执行文件通常被链接不同,常见譬如.text、.data、.rodata、.bss。...一个典型ELF文件包含下面几个:.text:已编译程序指令代码。.rodata:ro代表read only,即只读数据(譬如常数const)。.

1.8K30

C语言令人抓狂一面——全局变量

,了解这一点十分重要); 从空间分配上看,定义且初始化全局变量在编译时在数据(.data)分配空间,定义但未初始化全局变量**暂存(tentative definition)**在.bss编译时自动清零...这是一个多进程环境,首先我们看到无论父进程还是子进程,main.c还是foo.c,全局变量b和c地址仍然是一致(当然只是个逻辑地址),而且对b大小不同模块仍然不同决议。...还有一点值得注意,这个示例编译时没有出现第一个示例警告,即对变量bsizeof决议,笔者也不知道为什么,或许是GCC一个bug?...不过笔者有些无法解释这种行为原因,有种说法是强符号全局变量在数据中是连续分布(相应弱符号暂存在.bss或者符号表里),或许可以上报GNU编译器开发小组。...也许趁着你不注意时候她会偷偷给你戴顶绿帽,这一切都是通过全局变量,特别在动态链接环境下,就算全部定义成强符号仍然无法编译器所察觉。

68310

链接脚本linker script妙用

前面说过,编译器将源代码编译一个一个.o文件目标文件,这些文件又会存在各种依赖关系,所以将各种.o文件汇集到一起。 ? 这种方式编译出来程序,可以直接运行,不依赖于外部库文件。...3.链接脚本 一般在进行gcc进行链接时候,都会考虑到链接脚本(linker script),该文件一般以lds文件作为后缀名。...每个目标文件都有一些列,比如代码、数据bss等等。 ? 3.1 链接脚本实例分析 如果没有实际东西,那么说起理论来将索然无味。下面就具体来看下面的一个链接脚本布局。...,并且这个地址起始0x800000 (5).bss表示所有输入文件bss 上述从一个最简单链接脚本分析了链接脚本语法格式。...3.3 指定第一个文件链接 有的时候,需要考虑到链接顺序问题,比如在有些处理器中,系统从一个固定地址启动,但这个地址一定最开始时候会存放一个异常向量表。

4K10
领券