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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2023/11/30 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何在Visual Studio项目中正确添加汇编代码 . 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

引用注明>>?【作者:張佩】【鏡像:www.yiiyee.cn/blog】

?

1.??????問題描述

?

在以往的編程經(jīng)歷中,本人最常使用的匯編代碼是__asm {int 3}。它可以在我的代碼中插入一個(gè)軟件斷點(diǎn)。如果沒有一個(gè)連接到當(dāng)前程序的調(diào)試器,則程序?qū)⑼V乖谶@行語句處無法繼續(xù)執(zhí)行。

上面的這種方式稱為高級(jí)語言和匯編語言混編。當(dāng)我用得正爽的時(shí)候,迎頭碰到了64位平臺(tái)這員猛將。它大手一張,挑出一張禁令通知單:在64位編程中,高級(jí)語言和匯編混編將再也不被支持!兄弟我不禁暗暗垂淚,因?yàn)楫?dāng)我固執(zhí)而行的時(shí)候,若干惡心的編譯錯(cuò)誤赫然出現(xiàn)在我的面前:

[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'

  • ?上面的幾行所示的并非什么驚天動(dòng)地的大錯(cuò)誤,意思非常簡單:當(dāng)前架構(gòu)不支持__asm關(guān)鍵字。

    既然被踢出了體制外,我們要想生存,就必須得另謀出路。

    ?

    ?2. ? ? ?使用.asm文件

    ?

    在64位平臺(tái)上,我們遇到了翩然而至的.asm文件。在和她共舞的過程中,下面幾個(gè)步驟必須遵守:

    ?

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

    ?

    ?

    [cpp]?view plaincopy

  • FunName?PROC??
  • ????//?此處包含匯編指令???
  • FunName?ENDP??
  • FunName PROC

  • // 此處包含匯編指令

  • FunName ENDP

  • 這里面有兩個(gè)關(guān)鍵字分別表示函數(shù)的開始和結(jié)束:PROC和ENDP。我們看一個(gè)簡單的包含中斷指令的函數(shù)應(yīng)當(dāng)怎么寫。我們假設(shè)一個(gè).asm文件中僅有一個(gè)函數(shù)實(shí)現(xiàn),下面是一個(gè).asm匯編源文件的全部內(nèi)容:

    [cpp]?view plaincopy

  • //???
  • //?FILE:?test.asm???
  • //?Description:?匯編源文件。當(dāng)前文件僅在x64平臺(tái)上編譯,并不包含于x86平臺(tái),可通過設(shè)置源文件的屬性實(shí)現(xiàn)。???
  • //????
  • ??
  • .CODE?//?文件開始???
  • ??
  • //?函數(shù)原型:?void?Int_3()???
  • //?函數(shù)描述:函數(shù)實(shí)現(xiàn)中斷指令,沒有輸入/輸出參數(shù),也沒有返回值???
  • Int_3?PROC??
  • ???????int?3?//?中斷指令???
  • ???????ret???//?函數(shù)返回指令???
  • Int_3?ENDP??
  • ??
  • END??//?文件結(jié)束??
  • //

  • // FILE: test.asm

  • // Description: 匯編源文件。當(dāng)前文件僅在x64平臺(tái)上編譯,并不包含于x86平臺(tái),可通過設(shè)置源文件的屬性實(shí)現(xiàn)。

  • //

  • ?
  • .CODE // 文件開始

  • ?
  • // 函數(shù)原型: void Int_3()

  • // 函數(shù)描述:函數(shù)實(shí)現(xiàn)中斷指令,沒有輸入/輸出參數(shù),也沒有返回值

  • Int_3 PROC

  • int 3 // 中斷指令

  • ret // 函數(shù)返回指令

  • Int_3 ENDP

  • ?
  • END // 文件結(jié)束

  • 這個(gè)文件名為test.asm,文件包含名為Int_3的匯編函數(shù),函數(shù)本身僅有兩行代碼:中斷指令,返回指令。

    ?

    ?3.??????X86與X64的兼容

    ?

    現(xiàn)在澄清一下狀況:

    ?

  • 在X86平臺(tái)上,我們應(yīng)該使用混編方式執(zhí)行匯編指令;
  • 在X64平臺(tái)上,我們應(yīng)該使用.asm添加匯編函數(shù)。
  • ?

    ?

    ?

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

    [cpp]?view plaincopy

  • #ifdef?_M_AMD64???
  • ??//?這是x64平臺(tái)???
  • #else???
  • ??//?這是x86平臺(tái)???
  • #endif??
  • #ifdef _M_AMD64

  • // 這是x64平臺(tái)

  • #else

  • // 這是x86平臺(tái)

  • #endif

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

    ?

    [cpp]?view plaincopy

  • #include?<windows.h>???
  • ??
  • #ifdef?_AMD64_???
  • ??//?這是x64平臺(tái)???
  • #else???
  • ??//?這是x86平臺(tái)???
  • #endif??
  • #include <windows.h>

  • ?
  • #ifdef _AMD64_

  • // 這是x64平臺(tái)

  • #else

  • // 這是x86平臺(tái)

  • #endif

  • 如果我們只想在程序中添加一個(gè)軟中斷指令,則完整的實(shí)現(xiàn)示例如下:

    ?

    [cpp]?view plaincopy

  • #include?<windows.h>???
  • ??
  • extern?"C"?void?Int_3();??
  • ??
  • int?_tmain()??
  • {??
  • #ifdef?_AMD64_???
  • ???printf("這是x64平臺(tái),使用.asm匯編文件中定義的中斷函數(shù)\n");??
  • ???Int_3();??
  • #else???
  • ???printf("這是x86平臺(tái),使用__asm混編方式插入中斷指令\n");??
  • ???__asm?int?3;??
  • #endif???
  • ??
  • ??return?0;??
  • }??
  • #include <windows.h>

  • ?
  • extern "C" void Int_3();

  • ?
  • int _tmain()

  • {

  • #ifdef _AMD64_

  • printf("這是x64平臺(tái),使用.asm匯編文件中定義的中斷函數(shù)\n");

  • Int_3();

  • #else

  • printf("這是x86平臺(tái),使用__asm混編方式插入中斷指令\n");

  • __asm int 3;

  • #endif

  • ?
  • return 0;

  • }

  • ?

    4.??????Visual Studio編譯

    ?

    將.asm文件添加到項(xiàng)目中后,如果不做任何操作即直接編譯,我們會(huì)驚奇地發(fā)現(xiàn).asm文件被編譯器無視了(未被編譯)。為弄清個(gè)中緣由,請(qǐng)?jiān)?asm文件上右擊并選擇屬性,在彈出的屬性對(duì)話框中,你是否看到如下設(shè)置?

    ?

    由于這個(gè)文件的"項(xiàng)類型"被默認(rèn)設(shè)置為“不參與生成”,所以在編譯的時(shí)候,編譯器就不會(huì)帶上它。不曉得這一點(diǎn)在新的Visual Studio里面會(huì)不會(huì)有改正。這時(shí)候各位也不要慌了手腳,Visual Studio看上去對(duì).asm這個(gè)灰頭土臉的家伙有點(diǎn)不客氣,覺得它好面生,所以有什么活動(dòng)都不愿意帶上它。沒有關(guān)系,讓我們想辦法來讓它們熟悉起來吧。

    ?

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

    ?

    ?

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

    在右列面板中,我們有一些設(shè)置需要添加進(jìn)去,上圖中已由紅色方框標(biāo)出。

    ?

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

    ?

    ?

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

    總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。