C中的bss段 [英] bss segment in C

查看:31
本文介绍了C中的bss段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在问题关于Unix中的bss段和数据段》,我在bss上看到的解释如下:

In one of the answers to the question "Regarding the bss segment and data segment in Unix", I see the explanation on bss as follows:

Bss 很特别:.bss 对象不占用对象文件中的任何空间,并且通过将所有没有特别初始化的符号组合在一起,它们可以很容易地立即清零.

Bss is special: .bss objects don't take any space in the object file, and by grouping all the symbols that are not specifically intialized together, they can be easily zeroed out at once.

但是当我在目标文件上使用 size 时,生成的代码:

But when I use size on the object file, generated out of the code:

#include <stdio.h>
int uninit_global_var;
int init_global_var=5;

int main()
{
   int local_var;
   return 0;
}

我有以下内容

text    data      bss    dec     hex filename
1231     280      12    1523     5f3 a.out

并查看基于全局范围的未初始化数据成员的 bss 增长.那么任何人都可以证明上述声明的合理性吗?

and see the bss growing based on the uninitialized data members with global scope. So can anyone justify the mentioned statement?

推荐答案

如果您删除 stdio.h,您的输出可能会更有意义.让我们忽略那个库,因为它包含内部变量.

If you remove stdio.h your output will probably be more meaningful. Lets ignore that library, since it contains internal variables.

在您的具体情况下,会发生以下情况:

In your specific case, the following happens:

int uninit_global_var;

因为这是一个在文件范围中分配的变量,它具有静态存储期,就像任何声明为static的变量一样.C 标准要求,如果程序员未明确初始化具有静态存储持续时间的变量(如在这种情况下),则必须在程序启动之前将其设置为零.所有这些变量都放在 .bss 段中.

Since this is a variable allocated at file scope in has static storage duration, just as any variable declared as static. The C standard requires that if a variable with static storage duration is not initialized explicitly by the programmer, as in this case, it must be set to zero, before the program starts. All such variables are put in the .bss segment.

int init_global_var=5;

这个变量也是在文件范围内分配的,所以它也有静态存储期.但在这种情况下,它是由程序员初始化的.C 标准要求在程序启动之前将这些变量设置为给定的值.此类变量放置在 .data 段中.

This variable is also allocated at file scope, so it will also have static storage duration. But in this case it is initialised by the programmer. The C standard demands that such variables are set to the value given, before the program starts. Such variables are placed in the .data segment.

   int local_var;

此变量具有自动存储持续时间(本地).编译器很可能会优化掉这个变量,因为它没有任何用途.但是让我们假设这样的优化不会发生.该变量将在运行时分配,当它所在的作用域(块)被执行时,一旦该作用域结束(它超出作用域)就不再存在.它将在堆栈或 CPU 寄存器中分配.换句话说,在链接时,这个变量只作为程序代码存在,以某种汇编指令的形式存在,表示将一个 int 压入堆栈",然后从堆栈中弹出一个 int".

This variable has automatic storage duration (local). The compiler will most likely optimize away this variable as it fills no purpose. But lets assume that such optimization doesn't take place. The variable will then be allocated in runtime, when the scope (block) it resides in is executed and then cease to exist once that scope is finsihed (it goes out of scope). It will be allocated either on the stack or in a CPU register. In other words, at link time this variable only exists as program code, in the form of some assembler instruction saying "push an int on the stack" and then later "pop an int from the stack".

如何初始化这些不同类型的变量取决于系统.但通常编译器会在调用 main 之前注入一些代码.这是一种过度简化,但出于教学目的,您可以想象您的程序实际上是这样的:

How these different kind of variables are initialized depends on the system. But typically there will be some code injected by the compiler before main is called. This is an over-simplification, but for pedagogy's sake, you can imagine that your program actually looks like this:

bss
{
  int uninit_global_var;
}

data
{
  int init_global_var;
}

rodata
{
  5;
}


int start_of_program (void) // called by OS
{
  memset(bss, 0, bss_size);
  memcpy(data, rodata, data_size);

  return main(); 
}

数据:4bss:4

具有真正非易失性存储器的嵌入式系统将与上述代码完全相同,而基于 RAM 的系统可能会以不同的方式解决数据初始化部分.bss 在所有系统上的工作方式相同.

Embedded systems with true non-volatile memory will work exactly like the above code, while RAM-based systems may solve the data initialization part differently. bss works the same on all systems.

您可以通过运行以下程序轻松验证它们是否存储在不同的段中:

You can easily verify that they are stored in different segments by running the following program:

char uninit1;
char uninit2;
char init1 = 1;
char init2 = 2;

int main (void)
{
  char local1 = 1;
  char local2 = 2;

  printf("bss	%p	%p
", &uninit1, &uninit2);
  printf("data	%p	%p
", &init1, &init2);
  printf("auto	%p	%p
", &local1, &local2);
}

您将看到uninit"变量分配在相邻的地址,但与其他变量的地址不同.与init"变量相同.本地"变量可以分配到任何地方,因此您可以从这两个变量中获得任何类型的奇怪地址.

You will see that "uninit" variables are allocated at adjacent addresses, but at different addresses from the other variables. Same with "init" variables. "local" variables can be allocated anywhere so you get any kind of strange address as result from those two.

这篇关于C中的bss段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆