簡體   English   中英

如何從 C 文件中獲取完整的匯編代碼?

[英]How do I get a full assembly code from C file?

我目前正試圖找出從相應的 C 源文件生成等效匯編代碼的方法。

我已經使用C語言好幾年了,但對匯編語言的經驗很少。

我能夠使用 gcc 中的-S選項輸出匯編代碼。 但是,生成的匯編代碼包含調用指令,這些指令又會跳轉到另一個函數,如_exp 這不是我想要的,我需要在單個文件中編寫功能齊全的匯編代碼,而不依賴於其他代碼。

是否有可能實現我正在尋找的東西?

為了更好地描述問題,我在這里向您展示我的代碼:

#include <math.h>
float sigmoid(float i){
    return 1/(1+exp(-i));
}

我正在使用的平台是 Windows 10 64 位,我使用的編譯器是 MSbuild 的 cl.exe。

我最初的目標是在盡可能低的層次上了解計算機如何計算數學函數。 我決定觀察計算過程的層次是匯編代碼,我選擇的數學函數是如上定義的sigmoid。

_exp是標准的數學庫函數double exp(double) 顯然,您所在的平台在 C 符號名稱前加上了前導下划線。

給定一個調用一些庫函數的.s ,以與調用庫函數的.c文件相同的方式構建它:

gcc foo.S -o foo  -lm

默認情況下,您將獲得動態可執行文件。


但是,如果您真的希望將所有代碼都放在一個沒有外部依賴關系的文件中,您可以將您的.c鏈接到一個靜態可執行文件中並對其進行反匯編。

gcc -O3 -march=native foo.c -o foo -static -lm
objdump -drwC -Mintel foo > foo.s

不能保證libm.a (靜態庫)中的_exp實現與您在libm.solibm.dll或其他任何東西中獲得的相同,因為它是一個不同的文件。 對於像memcpy這樣的函數來說尤其如此,其中動態鏈接器技巧通常用於在運行時選擇最佳版本(對於您的 CPU)。

一般不可能,肯定有例外,我可以制作一個,這意味着其他人也可以,但這不是一個有趣的程序。

通常你的 C 程序,你的 main() 入口點只是代碼的一部分。 有一個引導程序,其中包含操作系統啟動程序的實際入口點,它會做一些准備虛擬內存空間以便程序可以運行的事情。 Zeros .bss 和其他類似的東西。 這通常和或應該用匯編語言編寫(否則你會遇到雞和蛋的問題)但不是匯編語言文件,除非你去找到 C 庫的源代碼,否則你經常會得到一個對象作為工具鏈以及其他編譯器庫等。

然后,如果您進行任何 C 調用或創建導致編譯器庫調用的代碼(在不支持除法的平台上執行除法,在沒有浮點的平台上執行浮點等),這是另一個來自其他一些 C 或程序集,它們是庫或編譯器源的一部分,在編譯/匯編/鏈接(工具鏈中的鏈)過程中不會看到。

因此,除了為此目的專門制作的瑣碎程序或專門制作的工具(針對特定的可能的裸機平台),您不會看到整個程序在組裝和鏈接之前變成一個大的匯編源文件。

如果不是裸機,那么當然有操作系統層,您肯定不會將其視為源代碼的一部分,最終需要系統的 C 庫調用將有一個地方可以執行此操作,所有這些都編譯為 object/ lib 在您使用它們之前,操作系統端的匯編源是其他源和構建過程的一部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM