我在尝试理解larger problem时正在进行一些测试。这是我的测试环境:
head.h :
#define MAX_BUFSIZE 500
typedef struct {
int head;
int tail;
int status;
int active;
void * dev[MAX_BUFSIZE];
char free[MAX_BUFSIZE];
int count;
} msg_fifo_t;
extern msg_fifo_t TxBufx[];
extern msg_fifo_t Rx_Buf[];
test.c的:
#include <stdio.h>
#include "head.h"
//msg_fifo_t TxBufx[10]; // This is the important line
int main(int argc, char * argv[])
{
// This part isn't really important...
printf("Hello Test\n");
return 0;
}
所以我使用这些文件并进行了三次测试,看看我得到了什么尺寸 -
测试#1(代码如上):
> gcc -Os test.c
> ls -al a.out
-rwxrwxr-x 1 mike mike 7158 Jan 17 11:13 a.out
> size a.out
text data bss dec hex filename
1170 256 8 1434 59a a.out
测试#2(取消注释“重要”行):
> gcc -Os test.c
> ls -al a.out
-rwxrwxr-x 1 mike mike 7181 Jan 17 11:14 a.out
> size a.out
text data bss dec hex filename
1170 256 25208 26634 680a a.out
测试#3(取消注释“重要”行并将TxBufx
大小更改为100)
> gcc -Os test.c
> ls -al a.out
-rwxrwxr-x 1 mike mike 7181 Jan 17 11:14 a.out
> size a.out
text data bss dec hex filename
1170 256 252008 253434 3ddfa a.out
现在我的问题是:
看起来bss大小几乎与可执行文件的“大小”没有关系(从ls -al
命令报告) - 任何人都可以向我解释为什么会这样吗?
该特性是否特定于编译器/链接器/或平台?
是否有比size
更好的工具来了解这里发生的事情? (这意味着什么才真正组成了我的可执行文件的7181字节?)
答案 0 :(得分:6)
bss
段中的数据量对可执行文件的磁盘大小没有影响,因为bss
段是 - 这是用于变量的程序部分< em>初始化为零。由于此部分的内容是事先知道的(全为零),因此实际存储在可执行文件中的唯一内容是该区域的 size 。
因此,做随着代码更改而改变的是data
段的大小 - 表示静态初始化为非零值的变量,以及{{的大小1}}段,表示与您的程序对应的已编译可执行指令。
对于要使用的工具,大多数Unix系统上的objdump(1)实用程序(它是GNU工具链的一部分)或MacOS X上的otool(1)实用程序都可用于获取有关哪些部分的更详细信息你的可执行文件,以及每个文件中的符号。
答案 1 :(得分:3)
bss
是UN初始化的内存。因此,它唯一需要存储的是每个变量的起始地址和大小。这就是为什么可执行文件的大小只增加了几个字节。
另外,即使是初始化的内存 - data
段 - 在可执行映像中也可能小于初始化变量的总大小。
而不是在可执行文件中创建初始化数据的完整图像,而是许多链接器插入如何初始化它的指令。因此,如果您已完成char buffer[500] = {1,1,1,1,1,1,1,...};
,则可执行文件的data
部分在概念上看起来像
&TxBufx: fill with 500 1's
除了地址将是段的字面开头。但是,如果您添加了全局unsigned char bytecode[500] = {0x12, 0x34, 0x55, ... }
,那么您的数据段将至少增加500个字节,因为它无法使用任何快捷方式。