为什么要区分BSS和COMMON部分? [英] Why differentiate BSS and COMMON section?

查看:187
本文介绍了为什么要区分BSS和COMMON部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我相信我的问题与此问题不同与此问题.在这里,我想问为什么我们需要区分这两个,所以该链接只能回答哪个去哪一个.

I believe my question is different to this one. Here I am asking why we need to differentiate those two, the link only answer which one goes to which.

我们知道:

  • 公共部分用于未初始化的全局变量和

  • Common section is for uninitialized global variables and

Bss部分用于未初始化的静态变量以及已初始化为0的全局变量.

Bss section is for uninitialized static variables plus global variable initialized to 0.

但是为什么要区分BSS和COMMON部分?特别是对于初始化为0的全局变量,我们不能将它们放在用于初始化全局变量的.data节中吗?将变量初始化为0也是一个初始化吗?

But why differentiate BSS and COMMON section? Especially for global variables initialized to 0, can't we put them in .data section which is for initialized global variables? Isn't that initialize a variable to 0 is also a initialization?

以下是我的教科书中的说明:

Below is an explanation from my textbook:

在某些情况下,链接器允许多个模块定义具有相同名称的全局符号.当编译器正在翻译某个模块并遇到弱的全局符号(例如x)时,它不知道其他模块是否也定义了x,如果这样,它将无法预测链接器可能选择x的多个实例中的哪个.因此,编译器通过将x分配给COMMON来将决定推迟到链接器.另一方面,如果x初始化为零,则它是一个强符号,因此编译器可以放心地将其分配给bss.

in some cases the linker allows multiple modules to define global symbols with the same name. When the compiler is translating some module and encounters a weak global symbol, say, x, it does not know if other modules also define x, and if so, it cannot predict which of the multiple instances of x the linker might choose. So the compiler defers the decision to the linker by assigning x to COMMON. On the other hand, if x is initialized to zero, then it is a strong symbol, so the compiler can confidently assign it to bss.

我真的很困惑,它说不知道其他模块是否也定义了x",但是如何两次定义一个变量?有示例代码可以说明吗?

I am really confused, it says "it does not know if other modules also define x", but how can you define a variable twice? Is an example code available to illustrate?

推荐答案

.bss部分用于出于优化目的分配零初始化数据,以允许

.bss section is used for allocating zero-initialized data for optimization purposes, to allow

  • 静态链接器,以减小可执行文件的大小(但不将零存储在其中)
  • 运行时链接程序(加载程序)可加快加载过程:通过映射填充有零的专用物理页或通过在启动时memset内存,可以有效地初始化公共数据.
  • static linker to reduce executable size (but not storing zeros in it)
  • runtime linker (loader) to speed up the loading process: common data is efficiently initialized either by mapping a dedicated physical page filled with zeroes or by memseting memory at startup.

使用公共"部分(在某些平台上,例如 Windows 而非ELF)来实现所谓的常见符号"即可以在不同的目标文件(翻译单元")中重复的符号.当此类符号落入公共部分时,静态链接器将合并所有单独的定义(具有某些特定于平台的规则,例如,仅在相同时合并,最好使用最大定义等).

Common section is used (on some platforms e.g. Windows but not ELF) to implement so called "common symbols" i.e. symbols which may be duplicated in different object files ("translation units"). When such symbol falls into a common section, static linker will merge all separate definitions (with some platform-specific rules, e.g. merge only if identical, prefer largest definition, etc.).

在某些目标上,公共部分仅用于未初始化的数据(这使它们与.bss有点相似),而在其他目标上,也用于

On some targets common sections are used only for uninitialized data (which make them somewhat similar to .bss) and on others also for vague symbols. In general there are no logical reasons for why different platforms made different choices regarding usage of common sections, it's purely historical.

您可以在[Raymond Chen的文章]中找到一些常见符号背后的历史 ( https://devblogs.microsoft.com/oldnewthing/20161024-00/?p = 94575 ).

You can find some history behind common symbols in [Raymond Chen's article] (https://devblogs.microsoft.com/oldnewthing/20161024-00/?p=94575).

这篇关于为什么要区分BSS和COMMON部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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