Сборка программ
Как правило, код и данные разбиты на именованные секции. В masm/tasm (MASM – Microsoft Assembler, Tasm – Turbo Assembler) такие секции называются сегментами, в DЕС'овских и UNIX'oвых ассемблерах – программными секциями (psect). В готовой программе весь код или данные, описанный в разных модулях, но принадлежащий к одной секции, собирается вместе. Например, в системах семейства Unix программы, написанные на языке С, состоят из минимум трех программных секций:
- .text – исполняемый код (современные компиляторы иногда помещают в эту секцию и данные, описанные как const);
- .data – статически инициализированные данные;
- .bss – неинициализированные данные.
В качестве упражнения читателю предлагается найти эти секции в примере 3.7.
Некоторые форматы объектных модулей, в частности ELF (Executable and Linking Format – формат исполняемых и собираемых [модулей], используемый современными системами семейства Unix), предоставляют особый тип глобального символа – слабый (weak) символ (пример 3.8). При сборке программы компоновщик не выдает сообщения об ошибке, если обнаруживает Два различных определения такого символа, при условии, что одно из определений является слабым – таким образом, слабый символ может быть легко переопределен при необходимости. Особенно полезен этот тип при помещении объектного модуля в библиотеку.
Пример 3.8. Структуры данных объектного модуля ELF (цитируется по elf.h из поставки Linux 2.2.16, перевод комментариев автора):
Заголовок файла ELF. Находится в начале каждого файла ELF. */ #define El NIDENT (16) typedef struct unsigned char e_ident[EI_NIDENT]; /* Магическое число и другая информация */ Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_0ff e_phoff; Elf32_0ff e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32__Half e_phentsize; Elf32_Half e_phnum; /* Elf32_Half e_shentsize; Elf32_Half e_shnum; /* Elf32_Half e_shstrndx; } Elf32 Ehdr; /* Тип объектного файла */ /* Архитектура */ /* Версия объектного файла */ /* Виртуальный адрес точки входа */ /* Смещение таблицы заголовка программы */ /* в файле */ /* Смещение таблицы заголовков секций в файле */ /* Процессорно-зависимые флаги */ /* Размер заголовка ELF в байтах */ /* Размер элемента */ /* таблицы заголовка программы */ Счетчик элементов таблицы заголовка программы */ /* Размер элемента таблицы заголовков секций */ Счетчик элементов таблицы заголовков программ */ /* Индекс таблицы имен секций в таблице заголовков секций */ /* Поля в массиве e_indent. Макросы Е1_* суть индексы в этом массиве. Макросы, следующие за каждым определением Е1_*, суть значения, которые соответствующий байт может принимать. */ #define EI_MAGO 0 /* Индекс нулевого байта сигнатуры1 */ fdefine ELFMAGO 0x7f /* Значение нулевого байта сигнатуры */ #define EI_MAG1 I /* Индекс первого байта сигнатуры */ #define ELFMAG1 'Е' /* Значение первого байта сигнатуры */ fdefine EI_MAG2 2 /* Индекс второго байта сигнатуры */ #define ELFMAG2 'L' /* Значение второго байта сигнатуры */ #define EI_MAG3 3 /* Индекс третьего байта сигнатуры */ #define ELFMAG3 'F' /* Значение третьего байта сигнатуры */ /* В данном случае – это "магическое число", код, размещаемый в определенном месте (обычно в начале) файла и подтверждающий, что это файл данного формата. /* объединение идентификационных байтов, для сравнения по словам */ #define ELFMAG "\177ELF" ((define SELFMAG 4 ((define EI_CLASS 4 /* Индекс байта, указывающего класс файла */ ((define ELFCLASSNONE 0 /* Не определено */ ((define ELFCLASS32 1 /* 32-разрядные объекты */ ((define ELFCLASS64 2 /* 64-разрядные объекты */ ((define ELFCLASSNUM 3 tdefine EI_DATA 5 /* Индекс байта кодировки данных */ ((define ELFDATANONE 0 /* Не определена кодировка данных */ ((define ELFDATA2LSB 1 /* Двоичные дополнительные, младший байт первый */ #define ELFDATA2MSB 2 /* Двоичные дополнительные, старший байт первый */ tdefine ELFDATANUM 3 #define EI_VERSION 6 /* Индекс байта версии файла */ /* Значение должно быть EV__CURRENT */ #define EIJDSABI 7 /*. идентификатор OS ABI */ tdefine ELFOSABI_SYSV 0 /* UNIX System V ABI */