Я читаю о библиотеках на C, но еще не нашел объяснения, что такое объектный файл. В чем реальная разница между любым другим скомпилированным файлом и объектным файлом?
Буду рад, если кто-нибудь сможет объяснить на человеческом языке.
Я читаю о библиотеках на C, но еще не нашел объяснения, что такое объектный файл. В чем реальная разница между любым другим скомпилированным файлом и объектным файлом?
Буду рад, если кто-нибудь сможет объяснить на человеческом языке.
Ответы:
Объектный файл - это реальный результат этапа компиляции. В основном это машинный код, но есть информация, которая позволяет компоновщику видеть, какие символы в нем есть, а также символы, необходимые для работы. (Для справки, «символы» - это в основном имена глобальных объектов, функций и т. Д.)
Компоновщик берет все эти объектные файлы и объединяет их в один исполняемый файл (при условии, что это возможно, т. Е. Что нет никаких повторяющихся или неопределенных символов). Многие компиляторы сделают это за вас (читай: они запускают компоновщик самостоятельно), если вы не скажете им «просто компилировать» с помощью параметров командной строки. ( -c
это распространенный вариант "просто компилировать; не связывать".)
Объектный файл - это сам скомпилированный файл. Между ними нет разницы.
Исполняемый файл формируется путем связывания объектных файлов.
Объектный файл содержит инструкции низкого уровня, понятные процессору. Вот почему его еще называют машинным кодом.
Этот низкоуровневый машинный код представляет собой двоичное представление инструкций, которые вы также можете написать напрямую с помощью языка ассемблера, а затем преобразовать код языка ассемблера (представленный на английском языке) в машинный язык (представленный в шестнадцатеричном формате) с помощью ассемблера.
Вот типичный высокоуровневый поток для этого процесса для кода на языке высокого уровня, таком как C
-> проходит препроцессор
-> чтобы дать оптимизированный код, все еще на C
-> проходит через компилятор
-> предоставить код сборки
-> проходит через ассемблер
-> предоставить код на машинном языке, который хранится в ФАЙЛАХ ОБЪЕКТОВ
-> проходит через линкер
-> получить исполняемый файл.
Этот поток может иметь некоторые вариации, например, большинство компиляторов могут напрямую генерировать код машинного языка, не используя ассемблер. Точно так же они могут сделать за вас предварительную обработку. Тем не менее, для лучшего понимания неплохо разбить составные части.
Есть 3 вида объектных файлов.
Содержат машинный код в форме, которую можно комбинировать с другими перемещаемыми объектными файлами во время компоновки, чтобы сформировать исполняемый объектный файл.
Если у вас есть a.c
исходный файл, чтобы создать его объектный файл с помощью GCC, вы должны запустить:
gcc a.c -c
Полный процесс будет выглядеть следующим образом: препроцессор (cpp) будет работать через переменный ток. Его вывод (все еще исходный) будет передан в компилятор (cc1). Его вывод (сборка) будет передан ассемблеру (as), который создаст файл relocatable object file
. Этот файл содержит объектный код и ссылки (и отладку, если-g
метаданные использовались) и не является исполняемым напрямую.
Специальный тип перемещаемого объектного файла, который может загружаться динамически, либо во время загрузки, либо во время выполнения. Совместно используемые библиотеки являются примером таких объектов.
Содержат машинный код, который может быть напрямую загружен в память (загрузчиком, например execve ) и впоследствии выполнен.
Результатом выполнения компоновщика нескольких файлов relocatable object files
является файл executable object file
. Компоновщик объединяет все входные объектные файлы из командной строки слева направо, объединяя все входные разделы одного типа (например, .data
) с выходными разделами того же типа. Он использует symbol resolution
и relocation
.
При связывании с a static library
функции, на которые есть ссылки во входных объектах, копируются в окончательный исполняемый файл. С dynamic libraries
таблицей символов создаются вместо этого даст возможность динамического связывания с библиотечными функциями / глобал. Таким образом, результатом является частично исполняемый объектный файл, так как он зависит от библиотеки. Если библиотека не существует, файл больше не может выполняться).
Процесс связывания может быть выполнен следующим образом:
ld a.o -o myexecutable
Команда: gcc a.c -o myexecutable
вызовет все команды, упомянутые в точке 1 и в точке 3 (cpp -> cc1 -> as -> ld 1 )
1: на самом деле это collect2, который является оболочкой над ld.
Объектный файл - это именно то, что вы получаете, когда компилируете один (или несколько) исходных файлов.
Это может быть либо полностью завершенный исполняемый файл или библиотека, либо промежуточные файлы.
Объектные файлы обычно содержат собственный код, информацию о компоновщике, отладочные символы и т. Д.
Объектные файлы - это коды, которые зависят от функций, символов и текста для запуска программы. Точно так же, как старые телексные машины, которые требовали телетайпа для отправки сигналов на другой телекс.
Точно так же, как процессору требуется двоичный код для запуска, объектные файлы похожи на двоичный код, но не связаны. Связывание создает дополнительные файлы, так что пользователю не нужно самостоятельно компилировать язык C. Пользователи могут напрямую открывать exe-файл после того, как объектный файл связан с каким-либо компилятором, например языком c, vb и т. Д.