.BSS如何分割并处理C程序的内存?
我试图理解.bss内存分配和Deallocation背后的逻辑,
我几乎没有尝试理解相同的情况。
我得出的结论是,如果我在代码的全局范围中声明任何变量,因为我的链接器脚本在8个字节中,它正在增加8个字节,
但是当我定义同一范围内的变量时,它是8个字节的。从.bss处理内存,
但是我不理解的是,DealLocation背后的逻辑计算到底是什么?
case1:
#include <stdio.h>
int a;
int b;
int main(void){
return 0;
}
此代码片段现在为不同的片段生成以下尺寸
text data bss dec hex filename
1418 544 16 1978 7ba a.out
,如果我初始化一个int变量(如这种
情况)2:
#include <stdio.h>
int a = 1;
int b;
int main(void){
return 0;
}
立即提供以下大小表
text data bss dec hex filename
1418 548 12 1978 7ba a.out
如果我在int varible之前初始化一个char(如the
Case 3),
#include <stdio.h>
char a = 1;
int b;
int main(void){
return 0;
}
请
text data bss dec hex filename
1418 545 12 1978 7ba a.out
这是Case 3的NM -N输出,
0000000000004000 D __data_start
0000000000004000 W data_start
0000000000004008 D __dso_handle
0000000000004010 D a
0000000000004011 B __bss_start
0000000000004011 D _edata
0000000000004014 b completed.8060
0000000000004018 D __TMC_END__
0000000000004018 B b
0000000000004020 B _end
如果我初始化一个类似于此情况的一个INT变量
一个int变量:
#include <stdio.h>
int a = 1;
char b;
int main(void){
return 0;
}
,现在显示出
text data bss dec hex filename
1418 548 4 1978 7ba a.out
如果我初始化一个类似于这种情况的一个int变量
,现在正在显示:
#include <stdio.h>
char a = 1;
char b;
int main(void){
return 0;
}
它显示了
text data bss dec hex filename
1418 545 7 1978 7ba a.out
任何人,请帮助我了解这一点吗?
I am trying to understand the logic behind the .bss memory allocation and deallocation
I have few cases which I have tried to understand the same.
I concluded that it is incrementing in the chunks of 8 bytes if I declare any variable in the global scope of the code because of the linker script of mine is having the alignment of 8 bytes
but when I define the variable inside the same scope it is deallocating the memory from the .bss
but exactly what is the logical calculations behind the deallocation is which I do not understand?
case1 :
#include <stdio.h>
int a;
int b;
int main(void){
return 0;
}
this code snippet generates the below sizes for the different segments
text data bss dec hex filename
1418 544 16 1978 7ba a.out
now if I initialize one int variable like this
case 2:
#include <stdio.h>
int a = 1;
int b;
int main(void){
return 0;
}
this gives me the following size table
text data bss dec hex filename
1418 548 12 1978 7ba a.out
now if I initialize one char before the int variable like this
case 3:
#include <stdio.h>
char a = 1;
int b;
int main(void){
return 0;
}
it is showing
text data bss dec hex filename
1418 545 12 1978 7ba a.out
this is the nm -n output specifically for the case 3
0000000000004000 D __data_start
0000000000004000 W data_start
0000000000004008 D __dso_handle
0000000000004010 D a
0000000000004011 B __bss_start
0000000000004011 D _edata
0000000000004014 b completed.8060
0000000000004018 D __TMC_END__
0000000000004018 B b
0000000000004020 B _end
now if I initialize one int variable like this
case 4:
#include <stdio.h>
int a = 1;
char b;
int main(void){
return 0;
}
it is showing
text data bss dec hex filename
1418 548 4 1978 7ba a.out
now if I initialize one int variable like this
case 5:
#include <stdio.h>
char a = 1;
char b;
int main(void){
return 0;
}
it is showing
text data bss dec hex filename
1418 545 7 1978 7ba a.out
anyone please help me to understand this ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
给定类型的符号具有链接器必须荣誉的自然对齐(例如
int
必须为4个字节对齐)。在给定的部分(例如.bss
)中,链接器有一些余地来重新排序符号,以使给定符号的对齐不会导致多余的填充。如果我们有:如果没有重新排序,则负载映射将看起来像:
,截面长度为8。
通过重新排序:
和,截面长度为5
请注意,各节的大小为 >向上到一些多个(通常为8个字节)。因此,例如,如果一个部分只有1个数据字节,则该部分的大小将报告为8。
但是,有例外。
更清楚地查看这一点的方法之一就是简化数据:
我们可以列出任何库或启动代码以降低可执行的大小。
我们可以使用相对于 first 数据部分的地址(例如
的开始> .data
)我创建了一个[Perl]脚本来做到这一点。它具有您的原始测试用例和一些其他测试用例。
特别值得注意的是情况6 ...
以下是脚本的输出。最终表[和讨论]在下面的最终部分中。
案例1:
来源:
命令:
nm -n Xfile
命令:
size xfile xfile
案例2:
source:
命令:命令:
NM -N XFILE
命令:
size xfile
案例3:
来源:
命令:
nm -n xfile
命令:<代码> size xfile
案例4:
来源:
命令:
nm -n xfile
命令:
size xfile xfile
案例5:
来源:
命令:
nm -n xfile
命令:
size xfile
案例6:
source:
命令:
nm -n xfile
命令:
大小xfile
最终:
请注意,在情况6中,
.data .data
长度为5。.bss
是[也] 5。 >)这是脚本来源:
Symbols of a given type have a natural alignment that the linker must honor (e.g.
int
must be 4 byte aligned). Within a given section (e.g..bss
), the linker has some leeway to reorder the symbols so that the alignment of a given symbol doesn't cause excess padding. If we have:Without the reordering, the load map would look like:
And, the section length would be 8.
With reordering:
And, the section length would be 5
Note that the size of the sections is aligned upward to some multiple (usually 8 bytes). So, for example, if a section has only 1 byte of data, the section size will be reported as 8.
But, there are exceptions.
One of the ways to see this more clearly is to simplify the data:
We can elide any libraries or startup code to reduce the executable size.
We can use addresses relative to the start of the first data section (e.g. start of
.data
)Combine results from all cases into a single table
I've created a [perl] script to do that. It has your original test cases and some additional ones.
Of particular note is case 6 ...
Below is the output of the script. The final table [and discussion] is in the FINAL section below.
Case 1:
Source:
Command:
nm -n xfile
Command:
size xfile
Case 2:
Source:
Command:
nm -n xfile
Command:
size xfile
Case 3:
Source:
Command:
nm -n xfile
Command:
size xfile
Case 4:
Source:
Command:
nm -n xfile
Command:
size xfile
Case 5:
Source:
Command:
nm -n xfile
Command:
size xfile
Case 6:
Source:
Command:
nm -n xfile
Command:
size xfile
FINAL:
Note that in case 6, the
.data
length is 5. And, the starting address of.bss
is [also] 5. But, the lowest.bss
address actually used is 8 (forb
)Here is the script source: