Открыть сервис

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 →