前言:
目前姐妹们对“c语言汇编程序”可能比较关怀,小伙伴们都想要知道一些“c语言汇编程序”的相关内容。那么小编也在网络上搜集了一些关于“c语言汇编程序””的相关内容,希望朋友们能喜欢,咱们快快来学习一下吧!初始化了的"静态变量和全局变量"保存在data段;没有初始化的"静态变量和全局变量"保存在bss段, 且初始值为0;
之前理解了C语言函数的局部变量存在于栈上,随着函数返回而释放,但静态变量与全局变量只要进程还在,就不会释放,也就不适合放在栈上,所以存储在数据区,可数据区为什么要分data段跟bss段呢?
验证1:初始化了的"静态变量和全局变量"保存在data段
下面是用来验证的例子:
#include<stdio.h>int global_init_value=8;int global_no_init_value;static int static_global_init_value=9;static int static_global_no_init_value;int main(){ int main_init_value = 1; static int static_main_init_value = 10; static int static_main_noinit_value; return 0;}
int global_init_value=8;static int static_global_init_value=9;static int static_main_init_value = 10
上面3个字段符合, 初始化了的"静态变量和全局变量", 接下来验证它们存在于data段。
1. 用 readelf -S test.o 输出所有段信息
由上图可知:data段的段索引为2,处于test.o文件0x54字节处,长度为0xC(十进制12);
2. 用readelf -s test.o输出test.o中的符号信息:
由上图可知:变量static_global_init_value, static_main_init_value, global_init_value 的段索引为2,也就是在data段,因为每个int占4个字节所以段大小为3*4=12字节,跟图1中data段的大小可以对上。
3. 用hexdump test.o以十六进制格式查看test.o文件
由上图可知:从0x54开始的12字节数据为0008 0000 0009 0000 000a 0000, 每个int占4字节,也就是十进制的8, 9, 10, 对应上了global_init_value, static_global_init_value, static_main_init_value的初始值。
结论初始化了的"静态变量和全局变量"的初始值确实保存在data段。没有初始化的"静态变量和全局变量"确实没保存在data段。验证2:没有初始化的"静态变量和全局变量"保存在bss段, 且初始值为0
同理,由图2可知,static_global_no_init_val, static_main_noinit_value 的段索引为3,也就是在bss段,而由图1可知,bss段的大小为8字节,刚好为2个int。由此验证了,没有初始化的"静态变量和全局变量"保存在bss段。
为什么静态变量跟全局变量要根据是否初始化保存在不同的段?
在图1中bss段与下个段(comment段)的偏移量均为0x60,说明bss段在test.o中并没有占任何字节,但data段占用了12字节,所以分出bss段是为了减小test.o文件的大小,系统会根据bss段的大小分配内存,并把内存的值初始化为0。
融会贯通C与汇编,以汇编的视角庖丁解牛C语言:栈上局部变量篇融会贯通C与汇编,以汇编的视角庖丁解牛C语言:栈上调用链篇融会贯通C与汇编,以汇编的视角庖丁解牛C语言:栈溢出攻击篇
创作不易,若帮助到了您,求点赞。 谢谢!