複製鏈接
請複製以下鏈接發送給好友

ABI

(應用程序二進制接口)

鎖定
每個操作系統都會為運行在該系統下的應用程序提供應用程序二進制接口(Application Binary Interface,ABI)。ABI包含了應用程序在這個系統下運行時必須遵守的編程約定。ABI總是包含一系列的系統調用和使用這些系統調用的方法,以及關於程序可以使用的內存地址和使用機器寄存器的規定。從一個應用程序的角度看,ABI既是系統架構的一部分也是硬件體系結構的重點,因此只要違反二者之一的條件約束就會導致程序出現嚴重錯誤。在很多情況下,鏈接器為了遵守ABI的約定需要做一些重要的工作。例如,ABI要求每個應用程序包含一個程序中各例程使用的靜態數據的所有地址表,鏈接器通過收集所有鏈接到程序中的模塊的地址信息來創建地址表。ABI經常影響鏈接器的是對標準過程調用的定義 [1] 
中文名
應用程序二進制接口
外文名
application binary interface
英文縮寫
ABI
學    科
計算機
作    用
定義應用程序在系統下運行時必須遵守的編程約定
含    義
源代碼和庫之間的接口

ABI簡介

ABI(Application Binary Interface):應用程序二進制接口,描述了應用程序和操作系統之間,一個應用和它的庫之間,或者應用的組成部分之間的低接口。ABI涵蓋了各種細節,如:
  • 數據類型的大小、佈局和對齊;
  • 調用約定(控制着函數的參數如何傳送以及如何接受返回值),例如,是所有的參數都通過棧傳遞,還是部分參數通過寄存器傳遞;哪個寄存器用於哪個函數參數;通過棧傳遞的第一個函數參數是最先push到棧上還是最後;
  • 系統調用的編碼和一個應用如何向操作系統進行系統調用;
  • 以及在一個完整的操作系統ABI中,目標文件二進制格式、程序庫等等。

ABI與應用程序接口區別

應用程序接口(Application Programming Interface,API),又稱為應用編程接口,就是軟件系統不同組成部分銜接的約定。由於近年來軟件的規模日益龐大,常常需要把複雜的系統劃分成小的組成部分,編程接口的設計十分重要。程序設計的實踐中,編程接口的設計首先要使軟件系統的職責得到合理劃分。良好的接口設計可以降低系統各部分的相互依賴,提高組成單元的內聚性,降低組成單元間的耦合程度,從而提高系統的維護性和擴展性。
ABI不同於API ,API定義了源代碼和庫之間的接口,因此同樣的代碼可以在支持這個API的任何系統中編譯 ,然而ABI允許編譯好的目標代碼在使用兼容ABI的系統中無需改動就能運行。 ABI掩蓋了各種細節,例如:調用約定控制着函數的參數如何傳送以及如何接受返回值;系統調用的編碼和一個應用如何向操作系統進行系統調用;以及在一個完整的操作系統ABI中,對象文件的二進制格式、程序庫等等。一個完整的ABI,像 Intel二進制兼容標準 (iBCS) ,允許支持它的操作系統上的程序不經修改在其他支持此ABI的操作系統上運行。其他的 ABI 標準化細節包括C++ name decoration和同一個平台上的編譯器之間的調用約定,但是不包括跨平台的兼容性。在Unix的操作系統中,存在很多運行在同一件平台上互相相關但是不兼容的操作系統(尤其是80386兼容系統)。有一些努力嘗試標準化A I,以減少銷售商將程序移植到其他系統時所需的工作。然而,還沒有很成功的例子,雖然LSB正在為Linux做這方面的努力。
它描述了應用程序與OS之間的底層接口。ABI涉及了程序的各個方面,比如:目標文件格式、數據類型、數據對齊、函數調用約定以及函數如何傳遞參數、如何返回值、系統調用號、如何實現系統調用等。
一套完整的ABI(比如:Intel Binary Compatibility Standard (iBCS)),可以讓程序在所有支持該ABI的系統上運行,而無需對程序進行修改。

ABI嵌入式應用二進制接口

嵌入式應用二進制接口 EABI(embedded application binary interface)指定了文件格式、數據類型、寄存器使用、堆積組織優化和在一個嵌入式軟件中的參數的標準約定。開發者使用自己的彙編語言也可以使用EABI作為與兼容的編譯器生成的彙編語言的接口。 支持EABI的編譯器創建的目標文件可以和使用類似編譯器產生的代碼兼容,這樣允許開發者鏈接一個由不同編譯器產生的庫。EABI與關於通用計算機的ABI的主要區別是應用程序代碼中允許使用特權指令,不需要動態鏈接(有時是禁止的),和更緊湊的堆棧幀組織用來節省內存。 廣泛使用EABI的有Power PC和ARM。

ABI鏈接器

鏈接器(Linker)是一個程序,將一個或多個由編譯器彙編器生成的目標文件外加庫鏈接為一個可執行文件。目標文件是包括機器碼和鏈接器可用信息的程序模塊。簡單的講,鏈接器的工作就是解析未定義的符號引用,將目標文件中的佔位符替換為符號的地址。鏈接器還要完成程序中各目標文件的地址空間的組織,這可能涉及重定位工作。
鏈接器的工作分3個步驟:
1、將代碼和數據模塊象徵性地放入內存。
2、決定數據和指令標籤的地址。
3、修補內部和外部引用。
鏈接器使用每個目標模塊中的重定位信息和符號表,來解析所有未定義標籤。這種引用發生在分支指令、跳轉指令和數據尋址處,所以這個程序的工作非常像一個編輯器:它尋找所有舊地址並用新地址取代它們:編輯是“鏈接編輯器”或鏈接器名字的簡稱。採用鏈接器的原因是修補代碼比重新編譯和彙編要快得多。
如果所有外部引用都解析完,鏈接器接着決定每個模塊將要佔用的內存位置。MlIPS在內存中為程序和數據分配空間的方式。因為文件是單獨彙編的,所以彙編器不可能知道該模塊的指令和數據相對於其他模塊而言將會被放到哪裏。當鏈接器將一個模塊放到內存中的時候,所有絕對引用(absolute reference),即與寄存器無關的內存地址必須重定位以反映它的真實地址。 [2] 
參考資料
  • 1.    JOHN R.LEVINE著,鏈接器和加載器,北京航空航天大學出版社,2009.09,第14頁
  • 2.    帕特森.計算機組成與設計:機械工業出版社,2015