Какие разделы составляют размер исполняемого файла?

Я провожу небольшой тест, пытаясь понять -executable">большая проблема. Вот моя тестовая среда:

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 байт, который является моим исполняемым файлом?)


person Mike    schedule 17.01.2013    source источник


Ответы (2)


Объем данных в сегменте bss не влияет на размер вашего исполняемого файла на диске, потому что сегмент bss — это раздел вашей программы, используемый для переменных, инициализированных нулем. Поскольку содержимое этого раздела известно заранее (все нули), в исполняемом файле фактически сохраняется только размер этого региона.

Таким образом, вещи, которые действительно изменяются по мере изменения вашего кода, — это размер сегмента data, представляющего переменные, статически инициализированные ненулевыми значениями, и размер сегмента code, представляющего скомпилированные исполняемые инструкции, соответствующие к вашей программе.

Что касается используемых инструментов, утилита objdump(1) в большинстве систем Unix (это часть набора инструментов GNU) или утилита otool(1) в MacOS X могут быть использованы для получения более подробной информации о том, какие разделы составляют ваш исполняемый файл. , и какие символы есть в каждом из них.

person jimwise    schedule 17.01.2013
comment
The amount of data in the bss segment has no effect on the size on disk of your executable - Это утверждение гарантировано? Как насчет другого компилятора/компоновщика, использующего цепочку инструментов coldfire для uCLinux? bss никогда и ни при каких обстоятельствах не будет включен в размер исполняемого файла? - person Mike; 17.01.2013
comment
Да. bss по определению - это только данные, инициализированные нулем. Нет причин для записи таких данных в файл. Напомним, что эта модель исполняемого файла Unix была разработана для миникомпьютерных систем семидесятых годов, которые на самом деле были гораздо больше ограничены в ресурсах, чем сегодняшние встроенные системы. :-) - person jimwise; 17.01.2013
comment
@Mike - Нет никаких гарантий, что все компиляторы на всех когда-либо созданных системах будут использовать сегмент bss. Это только широко используемая деталь реализации. - person Bo Persson; 17.01.2013
comment
Конечно. Но маловероятно, что другая цепочка инструментов (по крайней мере, в Unix-подобных системах) присвоит имя bss для обозначения фактического сегмента, содержащегося в исполняемом файле. :-) - person jimwise; 17.01.2013

bss — неинициализированная память. Таким образом, единственное, что ему нужно сохранить, — это начальный адрес каждой переменной и ее размер. Вот почему размер исполняемого файла увеличился всего на несколько байтов.

Кроме того, даже инициализированная память — сегмент 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 байт больше, поскольку он не может использовать ярлыки.

person AShelly    schedule 17.01.2013