web-dev-qa-db-ja.com

Application Binary Interface(ABI)について

Application Binary Interface(ABI)の概念を理解しようとしています。

From The Linux Kernel Primer

ABIは、呼び出し規約、マシンインターフェイス、オペレーティングシステムインターフェイスなど、リンカーが個別にコンパイルされたモジュールを再コンパイルせずに1つのユニットに結合できるようにする一連の規約です。特に、ABIはこれらのユニット間のバイナリインターフェイスを定義します。 ... ABIに準拠することの利点は、異なるコンパイラによってコンパイルされたオブジェクトファイルをリンクできることです。

Wikipedia から:

アプリケーションバイナリインターフェイス(ABI)は、アプリケーション(または任意のタイプ)プログラムとオペレーティングシステムまたは別のアプリケーションとの間の低レベルのインターフェイスを表します。

ABIは、データ型、サイズ、配置などの詳細をカバーしています。関数の引数の受け渡し方法と戻り値の取得方法を制御する呼び出し規約。システムコール番号、およびアプリケーションがオペレーティングシステムに対してシステムコールを行う方法。完全なオペレーティングシステムABIの場合は、オブジェクトファイルのバイナリ形式、プログラムライブラリなど。

  1. ABIが命令セットとOSの両方に依存しているかどうか疑問に思っていました。 ABIが依存しているのは2つだけですか?
  2. ABIは、コンパイルのさまざまな段階でどのような役割を果たしますか:前処理、Cからアセンブリへのコードの変換、アセンブリからマシンコードへのコードの変換、およびリンク?

    上記の最初の引用から、ABIはリンクステージにのみ必要であり、他のステージには必要ではないようです。それが正しいか?

  3. ABIはいつ検討する必要がありますか?

    C、アセンブリ、または他の言語でのプログラミング中にABIを考慮する必要がありますか?はいの場合、ABIとAPIはどのように異なりますか?

    それとも、リンカまたはコンパイラ専用ですか?

  4. ABIは、マシンコード、アセンブリ言語、および/またはCに対して指定されていますか?
5
Tim

Linux Kernel Primerからの回答は、おそらくLinuxカーネルに合わせて調整されています。ウィキペディアの答えはおそらくもっと一般的です。

最初の点では、ABIがプラットフォームに依存していることは確かです。 「プラットフォーム」の意味はさまざまです-物理ハードウェアを意味する場合もあれば、何らかの仮想マシンを意味する場合もあります。ABIは、言語やコンパイラによってある程度変動します。それ自体はプラットフォームに依存します。 ABIがO/Sによって部分的に定義されているかどうかは、プラットフォームとO/Sがどれだけ近いかに依存します。

ABIは生成されたアセンブラー(または他のコード)の動作方法に実質的に暗黙的であるため、コード生成(Cからの変換またはアセンブラーへの変換)はABIを認識する必要があります。たとえば、関数呼び出しのスタックフレームのレイアウト、特にパラメーターのレイアウトは、必要なスペースを予約してパラメーター値をそのスペースにコピーするアセンブラー命令によって実装されます。

高水準言語でコーディングする場合、ABIを詳細に知る必要があることは非常にまれですが、ABI関連のオプションを指定するためにisが必要になる場合があります。 C++でWindows PCをターゲットとする1つの例は、Pascalstdcallfastcallなどの呼び出し規約フラグの使用です。これらは、呼び出し元のABIが呼び出し先のABIと確実に一致するように、別の言語で記述されたコードとリンクしたり、別のコンパイラー(多くの場合、オペレーティングシステムサービス)を使用したりするときに必要になります。まれに、これらは最適化の理由で指定される場合があります。特定の状況では、一部の呼び出し規約が他の規約より効率的である場合があります。

アセンブラでコーディングし、オペレーティングシステムまたは別の言語で記述されたコードにリンクする場合は、それらの外部コンポーネントに適切なABIを使用する必要があります。ただし、独自のアセンブラーモジュール内では、実際のマシンまたは仮想マシンの制限にのみ依存して、独自のABIを発明するために、自由に好きなことを実行できます。

コンパイラは、関数が定義されている同じモジュール(オブジェクトファイル)内でのみ呼び出すことができることを知っている独自の「カスタム呼び出し規約」を構成することもできます。これは通常、最適化のために行われます。たとえば、その関数内で使用されないレジスタの保存を回避できる場合があります。したがって、限られた方法で、コンパイラはABIを即興で作成できます。

ただし、これはおそらく「ABI」という用語の乱用です。これらの即興の「インターフェース」は、定義により、モジュールのインターフェースにはまったくありません。

さまざまなプラットフォームにはさまざまな標準規則があります。これらは、プラットフォーム自体によって厳密に義務付けられている場合があります。たとえば、Javaおよび.NET仮想マシンに使用されるABIです。他の場合、デファクトスタンダードのABIは、特定の一般的なコンパイラによって定義されます。 。

Windows PCプラットフォームでのABIの状態は最も複雑だと思います。これは、さまざまな言語用の競合するコンパイラーがあり、少なくとも32ビットのWindowsが古いMS-DOSプログラムでさえサポートしている長い歴史があるためです。しかしもちろん、はるかに古いオペレーティングシステムがはるかに多様なハードウェアプラットフォームで使用されている-Unixは明らかなケース-なので、私は簡単にそれについて間違っているかもしれない。

4
Steve314