日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何在Visual Studio项目中正确添加汇编代码 .

發布時間:2023/11/30 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何在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'??
  • 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文件。在和她共舞的過程中,下面幾個步驟必須遵守:

    ?

  • 使用.asm文件包含匯編代碼;.asm文件以關鍵字.CODE開始,關鍵字END結束
  • 所有的匯編代碼以函數方式組織在一起,一個典型的函數聲明如下:
  • ?

    ?

    ?

    [cpp]?view plaincopy

  • FunName?PROC??
  • ????//?此處包含匯編指令???
  • FunName?ENDP??
  • 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??//?文件結束??
  • //

  • // 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平臺上,我們應該使用.asm添加匯編函數。
  • ?

    ?

    ?

    為了讓一段包含匯編指令的代碼能夠同時在X86和X64平臺上編譯通過,我們要有辦法讓編譯器自己判斷硬件平臺。編譯器提供了名為_M_AMD64的宏,只有在X64平臺上,這個宏才是被定義的。所以我們可以用類似下面的語法進行編程:

    [cpp]?view plaincopy

  • #ifdef?_M_AMD64???
  • ??//?這是x64平臺???
  • #else???
  • ??//?這是x86平臺???
  • #endif??
  • #ifdef _M_AMD64

  • // 這是x64平臺

  • #else

  • // 這是x86平臺

  • #endif

  • 實際上,大多數軟件都不使用_M_AMD64宏,而是使用在windows.h中定義的另一個表達同一含義的名為_AMD64_的宏。所以上文的另一種寫法如下:

    ?

    [cpp]?view plaincopy

  • #include?<windows.h>???
  • ??
  • #ifdef?_AMD64_???
  • ??//?這是x64平臺???
  • #else???
  • ??//?這是x86平臺???
  • #endif??
  • #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;??
  • }??
  • #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這個灰頭土臉的家伙有點不客氣,覺得它好面生,所以有什么活動都不愿意帶上它。沒有關系,讓我們想辦法來讓它們熟悉起來吧。

    ?

  • 首先,確保你當前的平臺是x64平臺。切記不要對x86平臺下的.asm文件做任何修改,因為.asm文件在x86平臺上是無法編譯的(目前為止,據我所知)。
  • 其次,請確保“從生成中排除”項的值是“否”。
  • 第三,讓我們點擊"項類型"的下標箭頭,會看到如下所示的眾多可選項:
  • ?

    ?

    ?

    第一個選項“C/C++編譯器”,是用來編譯.C/.cpp文件的,如果點擊一個.cpp文件看到的就會是它被默認選中。但匯編文件不能使用C/C++編譯器,讀者不信可以試一試,一定有亂七八糟的編譯錯誤秀出來。正確的做法是選擇“自定義生成工具”項,點擊“應用”后左列將出現名為“自定義生成工具”的子項,如下圖所示:

    在右列面板中,我們有一些設置需要添加進去,上圖中已由紅色方框標出。

    ?

  • 首先在“命令行”項中,我們應當輸入指定的編譯語句:ml64 /c?%(fileName).asm。這條命令的意思是使用ml64.exe.asm文件進行編譯,這里面的宏%(FileName)用來代指當前文件(test.asm)。命令行中的ml64乃指Ml64.exe編譯程序,它在Visual Studio的默認執行路徑中。把這條執行語句直接放在控制臺里面執行,一樣是能夠通過的。
  • 在“輸出”項中,我們設定輸出文件為:%(fileName).obj。即編譯后所生成的中間文件,而宏%(filename)含義如上。
  • ?

    ?

    ?

    確定并退出屬性對話框后,再次嘗試,會發現x86和x64平臺下的編譯都能夠成功了。我們通過上述方法,成功地在C/C++項目中添加匯編指令,并能夠在32/64位平臺上順利編譯通過。雖然我還沒有親自試驗,但相信相同的方法也能夠使用于.net等其他編程語言。

    總結

    以上是生活随笔為你收集整理的如何在Visual Studio项目中正确添加汇编代码 .的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。