我一直想知道可執行二進位檔案實際上是如何運作的。編譯總是聲明為
取得原始碼並將其翻譯為機器語言
但這到底意味著什麼呢?即:
- 我可以將二進位檔案從電腦 A 移動到電腦 B 並期望它正常工作嗎? (假設我也移動了適當的函式庫)
- 每個可執行二進位檔案都適合與特定處理器一起使用嗎?
- 可執行二進位檔案包含哪些類型的資訊?
- 為什麼Windows上的可執行檔可以在任何Windows版本上啟動? (如果有效的話那就是另一個故事了)
- 為什麼我無法在 Windows 上執行 Linux 執行檔?它與核心有關(所以與處理器無關)嗎?
請注意,我對處理器和編譯器的了解有限,並且對彙編一無所知。
答案1
- 不必要。如果它是為了可移植性而構建的並且平台兼容,那麼可以(例如,64 位元版本的 Windows 能夠執行 32 位元和 64 位元 Windows 可執行文件,但不再是 16 位元版本)。
- 不必要。它們是為特定指令集而設計的。由於這些通常是擴展並且具有向後相容性,因此您可能會在較新的處理器上運行較舊的文件,但不一定相反。例如,為 Windows 95 編譯的程式可能仍然可以在當今的硬體上運行,但是您無法在舊的 Windows 95 電腦上運行為當今的硬體編譯的程式。但是,如果兩台機器運行完全不同的指令,則可執行檔將不相容(例如 Intel 與 ARM)。
- 這是依賴平台的,有多種格式具有不同的標頭和內容,但基本上總是有某種標頭作為索引,告訴作業系統在哪裡可以找到特定的東西(例如主入口點)。
- 他們實際上不能(參見上面的#2)。
- 首先,Windows 和 Linux 的可執行檔使用不同的格式。但即便如此,還是存在差異,例如整個環境和提供的平台 API/函式庫。例如,Linux 可執行檔通常會嘗試與 X11 等視窗管理器通信,而 Windows 程式會嘗試呼叫 Windows API。然而,有一些方法可以讓這些事情發揮作用。舊版的 Windows(NT?)實際上具有 POSIX 擴展,因此據我所知,您可以運行一組有限的 Linux 程序,儘管我從未真正嘗試過或仔細研究過。另一方面,對於 Linux,有諸如 Wine 之類的工具,它將嘗試模擬 Windows 環境,提供 API 檔案、路徑轉換等。
答案2
僅在非常受控的情況下:兩台電腦必須具有相容的處理器和作業系統。
不是特定的處理器,而是一組相容的處理器。例如,假設作業系統相容,則為與 x86 相容而編譯且沒有副檔名的檔案將在每個 Intel 或 AMD x86 或 x64 處理器上執行。
首先也是最重要的是編譯步驟中的機器碼。除此之外,其他一些所謂的“部分”將具有例如資源(有沒有想過,為什麼可執行文件在Windows上有一個專用圖標,即使它沒有運行,但只是在資源管理器中顯示),二進制兼容性的描述和更多的。
這是1.的副作用:只要作業系統提供了與可執行格式的相容性,就可以啟動它。現代 Windows 版本提供了一系列相容性:DOS、Win16、Win32、Win64、dotnet 是最重要的。
作業系統為可執行檔提供了執行所需的環境。 Linux 和 Windows 之間的這些環境差異很大。這意味著,您無法直接從一個到另一個運行可執行檔。目前正在進行一些專案來彌補這一差距:WINE 專案旨在允許在 Linux(和其他作業系統)上啟動 Windows 可執行文件,而 Cygwin 專案旨在使 Linux 軟體能夠在 Windows 上運行。 Cygwin 的目標不是二進位相容性,而是允許重新編譯未修改的原始程式碼。
重要的是要理解,可執行檔(例如 .exe)是不是編譯過程的結果 - 這是連結過程,它將編譯的輸出與創建我在 3 中描述的內容所需的其他成分結合。