2016-11-12 101 views
2

我有一個完全用C編寫的項目。可以使用GCC for Linux或MSVC for Windows編譯相同的C文件。出於性能原因,我需要將一些代碼重新編寫爲x86彙編語言。我可以編寫(x86)使用GCC和MSVC構建的彙編語言嗎?

是否有可能將此彙編語言編寫爲將使用GCC和MSVC工具鏈構建的源文件?或者,如果我爲一個工具鏈編寫彙編源文件,是否有工具將其轉換爲與其他工具一起工作?

或者,我堅持要麼維護彙編源代碼的兩個副本,要麼使用第三方彙編器,例如NASM

+2

你問是因爲你的失敗還是因爲你調查過,沒有找到明確的答案?你是否意識到在這兩者之間調用約定的差異 - 如果有的話? – usr2564301

+0

我們在談論32位還是64位的程序集? – fuz

+0

內嵌程序集? – Banex

回答

4

我看到兩個問題:

  • MASM和天然氣有不同的語法。 gas可以配置爲使用Intel語法和.syntax intel,noprefix指令,但即使如此,仍然存在很小的差異(例如,不同的指令)。一種可能的方法是用C預處理器預處理彙編源代碼,使用宏指令來區分兩者之間的所有指令。這也具有提供統一評論語法的優點。

    但是,僅僅使用像nasm這樣的便攜式第三方彙編器很可能不那麼麻煩。

  • Linux和Windows有不同的調用約定。 x86-32的一個可能的解決方案是堅持一個支持良好的調用約定,如stdcall。您可以通過function attributes來告訴gcc調用函數時使用的調用約定。例如,這將宣告foo使用stdcall調用約定:

    extern int foo(int x, int y) __attribute__((stdcall)); 
    

    你可以在MSVC同樣的事情__declspec,解決這一問題。

    在x86-64上,可能會出現類似的解決方案,但我不確定您必須設置哪些屬性。

    您當然也可以使用與第一個問題相同的cpp方法來根據您需要的調用約定生成稍微不同的函數序言和結尾。但是,這可能不太可維護。

+0

在32位x86上,使用默認的「cdecl」調用約定更合理,這在Windows上的兩個Linux上都是一樣的。 –

+0

那麼,你的建議是使用第三方彙編程序嗎?那麼其他項目(包含彙編語言並支持多種操作系統)通常能解決這個問題嗎? – user200783

+0

@ user200783大多數情況下,當給定的CPU不受支持或給定的彙編程序不可用時,C代碼可以重新使用。 –