Что такое двоичный интерфейс приложения (ABI)? - PullRequest
405 голосов
/ 31 января 2010

Я никогда не понимал, что такое ABI. Пожалуйста, не указывайте мне статью в Википедии. Если бы я мог это понять, я бы не стал публиковать такие длинные сообщения.

Это мой взгляд на различные интерфейсы:

Пульт дистанционного управления - это интерфейс между пользователем и телевизором. Это существующий объект, но сам по себе бесполезный (не предоставляет никакой функциональности). Все функции каждой из этих кнопок на пульте реализованы в телевизоре.

Интерфейс: Это слой "существующий объект" между functionality и consumer этой функциональности. Интерфейс сам по себе ничего не делает Это просто вызывает функциональность, лежащую позади.

Теперь, в зависимости от того, кто пользователь, существуют различные типы интерфейсов.

Интерфейс командной строки (CLI) команды являются существующими объектами, потребитель - это пользователь, а функциональность - позади.

functionality: моя функциональность программного обеспечения, которая решает некоторые цель, для которой мы описываем этот интерфейс.

existing entities: команды

consumer: пользователь

Графический интерфейс пользователя (GUI) Окно, кнопки и т. Д. Являются существующими сущности, и снова потребитель является пользователем, а функциональность отстает.

functionality: моя программная функциональность, которая решает проблему, для которой мы описываем этот интерфейс.

existing entities: окно, кнопки и т.д ..

consumer: пользователь

Интерфейс прикладного программирования (API) функции (или быть более правильно) интерфейсы (в интерфейсном программировании) являются Существующие объекты, потребитель здесь другая программа, а не пользователь, и снова функциональность лежит за этим слоем.

functionality: моя функциональность программного обеспечения, которая решает некоторые Проблема, к которой мы описываем этот интерфейс.

existing entities: функций, интерфейсов (массив функций).

consumer: другая программа / приложение.

Двоичный интерфейс приложения (ABI) Здесь начинается моя проблема.

functionality: ???

existing entities: ???

consumer: ???

* * 1068 Я написал программное обеспечение на разных языках и предоставил различные виды интерфейсов (CLI, GUI и API), но я не уверен, что когда-либо предоставлял какой-либо ABI.

Википедия говорит:

ABI, такие как

  • тип данных, размер и выравнивание;
  • соглашение о вызовах, которое управляет аргументами функций переданные и возвращенные значения получены;
  • номера системных вызовов и как приложение должно выполнять системные вызовы к операционной системе;

Другие ABI стандартизируют детали, такие как

  • искажение имени в C ++,
  • распространение исключений и
  • Соглашение о вызовах между компиляторами на одной платформе, но не требует кроссплатформенной совместимости.
  • Кому нужны эти данные? Пожалуйста, не говорите ОС. Я знаю ассемблерное программирование. Я знаю, как работают ссылки и загрузка. Я точно знаю, что происходит внутри.

  • Почему в C ++ появилось искажение имен? Я думал, что мы говорим на двоичном уровне. Почему языки приходят?

В любом случае, я скачал двоичный интерфейс приложения [PDF] System V Edition 4.1 (1997-03-18) , чтобы увидеть, что именно в нем содержится. Ну, большая часть этого не имела никакого смысла.

  • Почему он содержит две главы (4-ю и 5-ю) для описания формата файла ELF ? На самом деле, это только две важные главы этой спецификации. Остальные главы посвящены «процессору». Во всяком случае, я думаю, что это совершенно другая тема. Пожалуйста, не говорите, что спецификации формата файлов ELF являются ABI. Он не может быть интерфейсом в соответствии с определением.

  • Я знаю, поскольку мы говорим на таком низком уровне, он должен быть очень конкретным. Но я не уверен, как это специфично для "архитектуры набора команд (ISA)"?

  • Где я могу найти ABI Microsoft Windows?

Итак, это основные запросы, которые меня беспокоят.

Ответы [ 15 ]

1 голос
/ 22 мая 2018

Термин ABI используется для обозначения двух разных, но связанных понятий.

Когда речь идет о компиляторах, это относится к правилам, используемым для перевода из конструкций исходного уровня в двоичные конструкции. Насколько велики типы данных? как работает стек? как передать параметры в функции? какие регистры должны быть сохранены вызывающим абонентом против вызываемого абонента?

Когда речь идет о библиотеках, это относится к двоичному интерфейсу, представленному скомпилированной библиотекой. Этот интерфейс является результатом ряда факторов, включая исходный код библиотеки, правила, используемые компилятором, а в некоторых случаях определения, взятые из других библиотек.

Изменения в библиотеке могут нарушить ABI, не нарушая API. Рассмотрим, например, библиотеку с интерфейсом вроде.

void initfoo(FOO * foo)
int usefoo(FOO * foo, int bar)
void cleanupfoo(FOO * foo)

и прикладной программист пишет код, подобный

int dostuffwithfoo(int bar) {
  FOO foo;
  initfoo(&foo);
  int result = usefoo(&foo,bar)
  cleanupfoo(&foo);
  return result;
}

Программисту приложения не важен размер или расположение FOO, но двоичный файл приложения заканчивается жестко заданным размером foo. Если программист библиотеки добавляет дополнительное поле в foo, и кто-то использует новый двоичный файл библиотеки со старым двоичным файлом приложения, то библиотека может получить доступ к памяти за пределами границ.

OTOH, если автор библиотеки разработал свой API как.

FOO * newfoo(void)
int usefoo(FOO * foo, int bar)
void deletefoo((FOO * foo, int bar))

и разработчик приложения пишет код, подобный

int dostuffwithfoo(int bar) {
  FOO * foo;
  foo = newfoo();
  int result = usefoo(&foo,bar)
  deletefoo(&foo);
  return result;
}

Тогда бинарному приложению не нужно ничего знать о структуре FOO, и все это можно спрятать внутри библиотеки. Цена, которую вы платите за это, хотя это то, что кучи операций.

1 голос
/ 21 июня 2017

Я также пытался понять ABI, и ответ JesperE был очень полезным.

С очень простой точки зрения, мы можем попытаться понять ABI, рассматривая двоичную совместимость.

Вики KDE определяет библиотеку как двоично-совместимую «если программа, динамически связанная с предыдущей версией библиотеки, продолжает работать с более новыми версиями библиотеки без необходимости перекомпиляции». Подробнее о динамическом связывании см. Static связывание против динамического связывания

Теперь давайте попробуем рассмотреть только самые основные аспекты, необходимые для библиотеки, чтобы быть двоичной совместимостью (при условии, что в библиотеке нет изменений исходного кода):

  1. Одинаковая / обратно совместимая архитектура набора команд (инструкции процессора, структура файла регистра, организация стека, типы доступа к памяти, наряду с размерами, компоновкой и выравниванием основных типов данных, к которым процессор может напрямую обращаться)
  2. Те же соглашения о вызовах
  3. Соглашение об одноименном названии (это может понадобиться, если, скажем, программе на Фортране нужно вызвать некоторую библиотечную функцию C ++).

Конечно, есть много других деталей, но в основном это то, что ABI также охватывает.

Более конкретно, чтобы ответить на ваш вопрос, из вышесказанного мы можем вывести:

Функциональность ABI: двоичная совместимость

существующие объекты: существующие программы / библиотеки / ОС

потребитель: библиотеки, ОС

Надеюсь, это поможет!

1 голос
/ 10 апреля 2013

Двоичный интерфейс приложения (ABI)

Функциональность:

  • Перевод из модели программиста в данные домена базовой системы тип, размер, выравнивание, соглашение о вызовах, которое контролирует, как аргументы функций передаются и возвращаемые значения извлекаются; номера системных вызовов и как приложение должно выполнять системные вызовы к операционной системе; имя компилятора языка высокого уровня схема искажения, распространение исключений и соглашение о вызовах между компиляторами на одной платформе, но не требуют кроссплатформенная совместимость ...

Существующие объекты:

  • Логические блоки, которые непосредственно участвуют в выполнении программы: ALU, регистры общего назначения, регистры для отображения памяти / ввода-вывода ввода-вывода и т. д. *

потребитель:

  • Языковые процессоры, компоновщик, ассемблер ...

Они нужны всем, кто должен обеспечить, чтобы цепочки инструментов сборки работали в целом. Если вы пишете один модуль на ассемблере, другой на Python и вместо собственного загрузчика хотите использовать операционную систему, тогда ваши «прикладные» модули работают через «двоичные» границы и требуют согласования такого «интерфейса».

C ++ искажение имен, поскольку в вашем приложении могут потребоваться ссылки на объектные файлы из разных языков высокого уровня. Рассмотрите возможность использования стандартной библиотеки GCC для выполнения системных вызовов Windows, созданных с использованием Visual C ++.

ELF - одно из возможных ожиданий компоновщика от объектного файла для интерпретации, хотя у JVM может быть другая идея.

Для приложения Магазина Windows RT попробуйте поискать ARM ABI, если вы действительно хотите, чтобы некоторые инструменты сборки работали вместе.

1 голос
/ 26 февраля 2010

Короче говоря, в философии только вещи типа могут хорошо ладить друг с другом, и ABI можно рассматривать как тип , из которых программные компоненты работают вместе.

1 голос
/ 31 января 2010

ABI должен быть согласованным между вызывающим и вызываемым абонентом, чтобы быть уверенным, что вызов успешен Использование стека, использование регистра, всплывающее окно в конце процедуры. Все это самые важные части ABI.

...