如何在Visual Studio项目中正确添加汇编代码 .
引用注明>>?【作者:張佩】【鏡像:www.yiiyee.cn/blog】
?
1.??????問題描述
?
在以往的編程經歷中,本人最常使用的匯編代碼是__asm {int 3}。它可以在我的代碼中插入一個軟件斷點。如果沒有一個連接到當前程序的調試器,則程序將停止在這行語句處無法繼續執行。
上面的這種方式稱為高級語言和匯編語言混編。當我用得正爽的時候,迎頭碰到了64位平臺這員猛將。它大手一張,挑出一張禁令通知單:在64位編程中,高級語言和匯編混編將再也不被支持!兄弟我不禁暗暗垂淚,因為當我固執而行的時候,若干惡心的編譯錯誤赫然出現在我的面前:
[html]?view plaincopy
1>test.cpp(98):error C4235: nonstandard extension used : '__asm' keyword not supported on thisarchitecture
1>test.cpp(98):warning C4091: '' : ignored on left of 'int' when no variable is declared
1>test.cpp(98):error C2143: syntax error : missing ';' before 'constant'
?上面的幾行所示的并非什么驚天動地的大錯誤,意思非常簡單:當前架構不支持__asm關鍵字。
既然被踢出了體制外,我們要想生存,就必須得另謀出路。
?
?2. ? ? ?使用.asm文件
?
在64位平臺上,我們遇到了翩然而至的.asm文件。在和她共舞的過程中,下面幾個步驟必須遵守:
?
?
?
?
[cpp]?view plaincopy
FunName PROC
// 此處包含匯編指令
FunName ENDP
這里面有兩個關鍵字分別表示函數的開始和結束:PROC和ENDP。我們看一個簡單的包含中斷指令的函數應當怎么寫。我們假設一個.asm文件中僅有一個函數實現,下面是一個.asm匯編源文件的全部內容:
[cpp]?view plaincopy
//
// FILE: test.asm
// Description: 匯編源文件。當前文件僅在x64平臺上編譯,并不包含于x86平臺,可通過設置源文件的屬性實現。
//
.CODE // 文件開始
// 函數原型: void Int_3()
// 函數描述:函數實現中斷指令,沒有輸入/輸出參數,也沒有返回值
Int_3 PROC
int 3 // 中斷指令
ret // 函數返回指令
Int_3 ENDP
END // 文件結束
這個文件名為test.asm,文件包含名為Int_3的匯編函數,函數本身僅有兩行代碼:中斷指令,返回指令。
?
?3.??????X86與X64的兼容
?
現在澄清一下狀況:
?
?
?
?
為了讓一段包含匯編指令的代碼能夠同時在X86和X64平臺上編譯通過,我們要有辦法讓編譯器自己判斷硬件平臺。編譯器提供了名為_M_AMD64的宏,只有在X64平臺上,這個宏才是被定義的。所以我們可以用類似下面的語法進行編程:
[cpp]?view plaincopy
#ifdef _M_AMD64
// 這是x64平臺
#else
// 這是x86平臺
#endif
實際上,大多數軟件都不使用_M_AMD64宏,而是使用在windows.h中定義的另一個表達同一含義的名為_AMD64_的宏。所以上文的另一種寫法如下:
?
[cpp]?view plaincopy
#include <windows.h>
#ifdef _AMD64_
// 這是x64平臺
#else
// 這是x86平臺
#endif
如果我們只想在程序中添加一個軟中斷指令,則完整的實現示例如下:
?
[cpp]?view plaincopy
#include <windows.h>
extern "C" void Int_3();
int _tmain()
{
#ifdef _AMD64_
printf("這是x64平臺,使用.asm匯編文件中定義的中斷函數\n");
Int_3();
#else
printf("這是x86平臺,使用__asm混編方式插入中斷指令\n");
__asm int 3;
#endif
return 0;
}
?
4.??????Visual Studio編譯
?
將.asm文件添加到項目中后,如果不做任何操作即直接編譯,我們會驚奇地發現.asm文件被編譯器無視了(未被編譯)。為弄清個中緣由,請在.asm文件上右擊并選擇屬性,在彈出的屬性對話框中,你是否看到如下設置?
?
由于這個文件的"項類型"被默認設置為“不參與生成”,所以在編譯的時候,編譯器就不會帶上它。不曉得這一點在新的Visual Studio里面會不會有改正。這時候各位也不要慌了手腳,Visual Studio看上去對.asm這個灰頭土臉的家伙有點不客氣,覺得它好面生,所以有什么活動都不愿意帶上它。沒有關系,讓我們想辦法來讓它們熟悉起來吧。
?
?
?
?
第一個選項“C/C++編譯器”,是用來編譯.C/.cpp文件的,如果點擊一個.cpp文件看到的就會是它被默認選中。但匯編文件不能使用C/C++編譯器,讀者不信可以試一試,一定有亂七八糟的編譯錯誤秀出來。正確的做法是選擇“自定義生成工具”項,點擊“應用”后左列將出現名為“自定義生成工具”的子項,如下圖所示:
在右列面板中,我們有一些設置需要添加進去,上圖中已由紅色方框標出。
?
?
?
?
確定并退出屬性對話框后,再次嘗試,會發現x86和x64平臺下的編譯都能夠成功了。我們通過上述方法,成功地在C/C++項目中添加匯編指令,并能夠在32/64位平臺上順利編譯通過。雖然我還沒有親自試驗,但相信相同的方法也能夠使用于.net等其他編程語言。
總結
以上是生活随笔為你收集整理的如何在Visual Studio项目中正确添加汇编代码 .的全部內容,希望文章能夠幫你解決所遇到的問題。