Исполня́емый файл — набор инструкций, который заставляет компьютер выполнить определённую задачу[1]. В отличие от текстового файла, который рассчитан на чтение человеком, исполняемый файл рассчитан на чтение (и выполнение) процессором.
Под «инструкциями» традиционно понимается машинный код, который выполняется напрямую физическим процессором[2]. В некоторых случаях файл, содержащий инструкции сценария промежуточного языка программирования (например, байт-код), также может считаться исполняемым.
Создание исполняемых файлов
правитьИсполняемые файлы могут быть созданы вручную на машинном языке, но этот подход обычно не используется из-за отсутствия как такового синтаксиса и удобочитаемости кода, поэтому гораздо удобнее разрабатывать исполняемые программы на языке программирования высокого уровня, который доступен для понимания. В некоторых случаях исходный код может быть на языке ассемблера, который остается удобочитаемым, но при этом предназначен для работы с инструкциями машинного кода.
Код на языке высокого уровня компилируется в объектные файлы машинного кода, которые не являются исполняемыми. После код может быть скомпонован в исполняемый файл. Этот процесс на языке ассемблера называется линковкой. Объектные файлы в зависимости от операционной системы обычно хранятся в формате контейнера (при котором различные данные содержатся в одном файле), таком как Executable and Linkable Format (ELF) для Unix-подобных систем или Portable Executable (PE) для Windows[3]. Это придает структуру машинному коду, разделяя его на секции, такие как .text (выполняемый код), .data (инициализированные глобальные и статические переменные) и .rodata (данные только для чтения, такие как постоянные и строки).
Исполняемые файлы обычно включают в себя среду выполнения, которая реализует функции языка программирования и компилятора среды выполнения (такие как планирование, обработка исключений, вызов статических конструкторов и деструкторов и т. д.) и взаимодействие с операционной системой, в частности, передача аргументов, окружения и кода возврата, вместе с другими функциями при запуске и завершении программы, которые не были указаны программистом, но представляющие ценность для последующей работы, такие как исполнение ресурсов. В Си это делается путем линковки компоновщиком объектного файла crt0 в исполняемый файл, который содержит точку исполнения, выполняет настройку и завершает работу с помощью вызова библиотеки среды выполнения[4].
Таким образом, исполняемые файлы обычно содержат дополнительный машинный код, который генерируется компилятором определённым образом из исходного кода. Это в некоторых случаях желательно пропустить, например, для разработки встроенных систем или просто для понимания того, как работают компиляция, линковка и загрузка. В Си пропустить стандартную среду выполнения можно с помощью указания сценария компоновщика напрямую, к примеру, вызвать main
функцию для запуска программы и возвратить статус выхода ядру[5].
Исполнение
правитьДля выполнения операционной системой, прошивкой или загрузчиком, исполняемый файл должен соответствовать бинарному интерфейсу приложений (ABI)[6]. В простых интерфейсах файл выполняется путем загрузки в память, перехода (прыжка) к началу адресного пространства и выполнения оттуда. В более сложных интерфейсах исполняемые файлы имеют дополнительные данные, определяющие отдельную точку входа. Например, в ELF точка входа указывается в заголовке e_entry
, который указывает (виртуальный) адрес памяти, с которого следует начать выполнение. В GCC вход устанавливается компоновщиком с помощью символа _start
.
См. также
правитьПримечания
править- ↑ executable . Merriam-Webster's Online Dictionary. Merriam-Webster. Дата обращения: 19 июля 2008. Архивировано 25 апреля 2009 года.
- ↑ Machine Instructions (амер. англ.). GeeksforGeeks (3 ноября 2015). Дата обращения: 18 сентября 2019. Архивировано 21 декабря 2019 года.
- ↑ Chapter 4: Object Files . refspecs.linuxbase.org. Дата обращения: 18 сентября 2019.
- ↑ Fisher. List of Executable File Extensions (англ.). lifewire.com. Дата обращения: 18 сентября 2019. Архивировано 11 сентября 2019 года.
- ↑ McKellar. Hello from a libc-free world! (Part 1) (16 марта 2010). Дата обращения: 17 августа 2021. Архивировано 17 ноября 2016 года.
- ↑ Boelen. The 101 of ELF files on Linux: Understanding and Analysis - Linux... (англ.). Linux Audit (15 мая 2019). Дата обращения: 18 сентября 2019. Архивировано 28 апреля 2019 года.