1
ShangShanXiaShan 2019-07-29 11:34:03 +08:00
未初始化的全局变量放在 bss
|
2
wangyaominde 2019-07-29 11:58:53 +08:00
生成文件的大小难道不是生成的机器码的大小吗?
|
3
BingoXuan 2019-07-29 12:02:12 +08:00
应该是编译器做了优化吧
|
4
zealot0630 2019-07-29 12:06:26 +08:00 3
objdump -t ./a.out 会告诉你答案
|
5
wangyaominde 2019-07-29 12:07:23 +08:00 1
https://i.loli.net/2019/07/29/5d3e6fc3702bc64628.png
左侧是未注释的,汇编就差一句 https://i.loli.net/2019/07/29/5d3e70930490b24948.png 这个是 int a[30]={1,2,3...30};的,之前遇到过编译器自作聪明删掉变量的。。。。猜测跟编译器相关。 |
6
zealot0630 2019-07-29 12:07:28 +08:00 1
配合 objdump -h 食用
|
7
VDimos 2019-07-29 12:11:13 +08:00 via Android
文件大小和 has data ?
|
8
iAcn 2019-07-29 12:11:34 +08:00 via Android
编译器把未使用的全局变量删了吧。
|
9
menyakun 2019-07-29 13:27:44 +08:00
对于链接后的可执行文件来说,各个 section 之间是有很多 gap 的。你按数据大小来算文件大小,对比链接前的目标文件的话会更有可比性一点
|
10
takeoffyoung 2019-07-29 13:32:12 +08:00 1
代码编译之后可执行文件占用磁盘的大小和代码运行时占用内存的大小有啥关系呢。
总不能说你的代码里面声明了一个占内存 10 个 G 的变量,你编译的可执行文件会占用 10 个 G 的磁盘空间? |
11
zyp0921 2019-07-29 13:41:09 +08:00 1
可以去看看程序员的自我修养这本书。。。强力推荐哟
|
12
johnkiller 2019-07-29 13:53:44 +08:00
@takeoffyoung 正解
|
13
kljsandjb 2019-07-29 13:58:18 +08:00 via iPhone
机器码啊,你比较一下,指令都是编码成二进制的
|
14
johnkiller 2019-07-29 14:00:53 +08:00
int a[100];
int a[999]; 文件占用肯定都一样, 我觉得文件的大小与生成的汇编语句量有关,而不是变量的大小啊,变量跟内存才有关 个人理解,接受指正 |
15
season4675 2019-07-29 14:05:32 +08:00
你这是内存使用情况啊,和文件大小没关系啊……
|
16
johnkiller 2019-07-29 14:06:14 +08:00
1. malloc int, 100
2. malloc flt, 999 抽象描述大概应该就是这个意思,字符长度都一样,但是运行时内存占用不一样 |
17
menyakun 2019-07-29 14:08:58 +08:00
@takeoffyoung 如果你声明并初始化了一个占 10 个 G 的全局变量或这 static 变量的话,编译后的文件的确会占 10 多个 G
|
18
takeoffyoung 2019-07-29 14:20:24 +08:00
@menyakun 并不会,除非你的初始化是用相等长度的代码来实现的。这两者就是没有关系,如果在代码中用写下一千万个数字来初始化长度为一千万的数字。这种方式导致的可执行文件的大小的变化,并不能归纳到你的结论上。
|
19
Nitroethane 2019-07-29 14:22:36 +08:00 via Android
@ShangShanXiaShan 一楼正解
|
20
menyakun 2019-07-29 14:30:14 +08:00
@takeoffyoung 不是这个道理,就算再大的数组,只要有一个成员被初始化了,那么其他的文件就可以修改这个数组里的值,所以这个数组必须在链接时就被初始化,这样涉及到这个数组的汇编才能生成。重申一下,这里说的都是全局变量和局部静态变量。
|
21
ShangShanXiaShan 2019-07-29 14:51:58 +08:00
@menyakun 我没理解 “其他文件可以修改这个数组的值” 是什么意思。其他文件指的是其他源码文件?如果是,那么其他文件对这个数组的引用应该也是发生在运行时吧?这样子的话跟链接时是否初始化这个数组并没有多大的关系。
@takeoffyoung 只要对数组的一个成员进行初始化并且值不为 0,那么该数组将被放置在 data 段,data 段的内容会被写到可执行文件中。 |
22
menyakun 2019-07-29 15:08:36 +08:00
@ShangShanXiaShan 对,是我理解岔了。bss 段只是一个对可执行文件大小的优化处理,bss 段和 data 段的变量在汇编代码生成的时候是一样的
|
23
fvckDaybyte2 OP @wangyaominde 请教下,这个是怎么弄出来的,是用楼上的 objdump 吗
|
24
fvckDaybyte2 OP @zealot0630 objdump -t data_bss_test_0
data_bss_test_0: file format Mach-O 64-bit x86-64 SYMBOL TABLE: 0000000100000000 g F __TEXT,__text __mh_execute_header 0000000100000f60 g F __TEXT,__text _main 0000000000000000 *UND* _printf 0000000000000000 *UND* dyld_stub_binder 看得不是很懂😂 |
25
wangyaominde 2019-07-31 10:25:39 +08:00 1
@fvckDaybyte2 直接 gcc -S 生成.s 的汇编文件
|
26
fvckDaybyte2 OP @wangyaominde 谢谢
|