ABI
ABI (от англ. Application Binary Interface — двоичный интерфейс приложений) — это набор правил и соглашений, определяющих взаимодействие между программными модулями на уровне двоичного кода. В отличие от API (Application Programming Interface), который описывает взаимодействие на уровне исходного кода, ABI регламентирует, как данные и управляющие команды передаются между исполняемыми файлами, библиотеками и операционной системой на уровне машинных инструкций. ABI включает в себя такие аспекты, как формат вызова функций (calling convention), способы передачи аргументов, правила выравнивания данных, размеры и представление базовых типов, а также формат исполняемых файлов и библиотек.
История
Понятие ABI возникло в 1970-х годах с развитием многозадачных операционных систем и динамических библиотек. Первые реализации ABI были разработаны для систем Unix, где требовалась совместимость между разными версиями ядра и прикладного ПО. В 1980-х годах компания AT&T опубликовала спецификацию System V ABI, которая стала стандартом для многих Unix-подобных систем, включая Linux. В 1990-х годах с распространением Windows компания Microsoft разработала собственный ABI для платформы x86, известный как Microsoft ABI. В 2000-х годах с развитием мобильных платформ и встраиваемых систем появились специализированные ABI, такие как ARM ABI и MIPS ABI.
Основные компоненты ABI
Соглашения о вызове (Calling Convention)
Соглашения о вызове определяют, как функции передают аргументы и получают возвращаемые значения. Включают в себя:
- Порядок передачи аргументов (через регистры, стек или их комбинацию).
- Правила сохранения и восстановления регистров вызываемой функцией.
- Механизм обработки возвращаемых значений (через регистры или память).
- Обработку исключений и раскрутку стека (stack unwinding).
Наиболее распространённые соглашения о вызове: cdecl (для C/C++ на x86), stdcall (для Windows), fastcall (с передачей через регистры), System V AMD64 (для Linux и macOS на x86-64), ARM AAPCS (для ARM-архитектур).
Формат исполняемых файлов
ABI определяет структуру бинарных файлов, таких как исполняемые файлы и динамические библиотеки. Включает:
- Формат заголовков (ELF для Unix-подобных систем, PE для Windows, Mach-O для macOS).
- Секции кода, данных, символов и таблиц перемещений.
- Механизмы загрузки и связывания (статического и динамического).
Представление данных
ABI устанавливает:
- Размеры и выравнивание базовых типов (char, int, long, float, double и т.д.).
- Порядок байтов (endianness) — little-endian или big-endian.
- Структуры и объединения: правила выравнивания полей, размер и упаковка.
- Представление указателей и ссылок.
Обработка исключений
ABI может включать механизмы для обработки исключений на уровне двоичного кода, такие как:
- Таблицы раскрутки стека (unwind tables) для корректного освобождения ресурсов.
- Специфические для платформы исключения (например, SEH в Windows, DWARF в Linux).
Классификация ABI
По уровню
- Системный ABI — определяет взаимодействие между приложениями и операционной системой. Включает системные вызовы, форматы файлов и общие соглашения.
- Языковой ABI — специфичен для конкретного языка программирования (например, C++ ABI включает правила для виртуальных функций, RTTI, исключений).
- Библиотечный ABI — описывает интерфейс между библиотекой и использующим её кодом. Стабильность библиотечного ABI критична для обратной совместимости.
По платформе
- x86 ABI — для 32-битных процессоров Intel/AMD. Включает System V ABI (Linux, Unix) и Microsoft ABI (Windows).
- x86-64 ABI — для 64-битных процессоров. Наиболее распространён System V AMD64 ABI.
- ARM ABI — для архитектуры ARM. Включает AAPCS (ARM Architecture Procedure Call Standard) и его варианты для разных версий ARM.
- MIPS ABI — для процессоров MIPS. Включает o32, n32, n64 и другие варианты.
- RISC-V ABI — для открытой архитектуры RISC-V, стандартизирован в спецификации RISC-V ABI.
Применение
Совместимость программного обеспечения
ABI обеспечивает возможность запуска программ, скомпилированных на разных версиях компиляторов, с разными динамическими библиотеками. Например, в Linux программы, собранные с одной версией glibc, могут работать с другой версией, если ABI остаётся совместимым.
Разработка и отладка
Знание ABI необходимо для:
- Написания низкоуровневого кода (ассемблер, драйверы).
- Отладки и анализа сбоев (core dump, трассировка стека).
- Разработки компиляторов и линковщиков.
- Создания библиотек, совместимых с разными языками (например, вызов C-функций из Python или Java).
Виртуализация и эмуляция
ABI используется для эмуляции одной платформы на другой, например, при запуске Windows-приложений на Linux через Wine или при эмуляции ARM-приложений на x86.
Критика и проблемы
Нестабильность ABI
Изменения в ABI могут привести к несовместимости между версиями программного обеспечения. Например, обновление библиотеки с изменением ABI требует перекомпиляции всех использующих её приложений. Это особенно проблематично в экосистемах с динамической загрузкой библиотек, таких как Windows и Linux.
Сложность поддержки
Поддержка нескольких ABI на одной платформе (например, 32-битных и 64-битных приложений) увеличивает сложность операционной системы и требует дополнительных механизмов, таких как thunking и WoW64 (Windows-on-Windows 64-bit).
Различия между платформами
Разные операционные системы и архитектуры имеют разные ABI, что затрудняет переносимость бинарного кода. Например, приложение, скомпилированное для Linux на x86-64, не может быть запущено на Windows без эмуляции или перекомпиляции.
Примеры
- System V ABI — стандарт для Unix-подобных систем, включая Linux. Определяет соглашения для x86, x86-64, ARM и других архитектур.
- Microsoft ABI — используется в Windows для x86 и x86-64. Включает специфические соглашения, такие как stdcall и fastcall.
- ARM ABI — стандарт для ARM-процессоров, используемый в Android, iOS и встраиваемых системах.
- Itanium C++ ABI — стандарт для C++ на платформе Itanium, который стал основой для многих современных C++ ABI (включая GCC и Clang).
Интересные факты
- В Linux для обеспечения обратной совместимости используется механизм версионирования символов (symbol versioning), позволяющий библиотекам поддерживать несколько версий ABI.
- В Windows ABI может меняться между версиями операционной системы, что иногда приводит к сбоям в работе старых приложений.
- Некоторые языки программирования, такие как Rust и Go, имеют собственные ABI, которые могут отличаться от системного ABI, что требует специальных механизмов для взаимодействия с C-библиотеками.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →


