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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

在 Visual C++ 中使用内联汇编

發(fā)布時間:2025/3/15 c/c++ 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在 Visual C++ 中使用内联汇编 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在 Visual C++ 中使用內(nèi)聯(lián)匯編
?

?

一、 優(yōu)點
?

??? 使用內(nèi)聯(lián)匯編可以在 C/C++ 代碼中嵌入?yún)R編語言指令,而且不需要額外的匯編和連接步驟。在 Visual C++ 中,內(nèi)聯(lián)匯編是內(nèi)置的編譯器,因此不需要配置諸如 MASM 一類的獨立匯編工具。這里,我們就以 Visual Studio .NET 2003 為背景,介紹在 Visual C++ 中使用內(nèi)聯(lián)匯的相關(guān)知識(如果是早期的版本,可能會有些許出入)。

?

??? 內(nèi)聯(lián)匯編代碼可以使用 C/C++ 變量和函數(shù),因此它能非常容易地整合到 C/C++ 代碼中。它能做一些對于單獨使用 C/C++ 來說非常笨重或不可能完成的任務(wù)。

?

??? 內(nèi)聯(lián)匯編的用途包括:

?

l?????? 使用匯編語言編寫特定的函數(shù);

l?????? 編寫對速度要求非常較高的代碼;

l?????? 在設(shè)備驅(qū)動程序中直接訪問硬件;

l?????? 編寫 naked 函數(shù)的初始化和結(jié)束代碼。

?

?

二、 關(guān)鍵字
?

??? 使用內(nèi)聯(lián)匯編要用到 __asm 關(guān)鍵字,它可以出現(xiàn)在任何允許 C/C++ 語句出現(xiàn)的地方。我們來看一些例子:

?

l?????? 簡單的 __asm 塊:

?

??????? __asm

??????? {

??????????? MOV AL, 2

??????????? MOV DX, 0xD007

??????????? OUT AL, DX

??????? }

?

l?????? 在每條匯編指令之前加 __asm 關(guān)鍵字:

?

??????? __asm MOV AL, 2

??????? __asm MOV DX, 0xD007

??????? __asm OUT AL, DX

?

l?????? 因為 __asm 關(guān)鍵字是語句分隔符,所以可以把多條匯編指令放在同一行:

?

??????? __asm MOV AL, 2? __asm MOV DX, 0xD007? __asm OUT AL, DX

?

??? 顯然,第一種方法與 C/C++ 的風格很一致,并且把匯編代碼和 C/C++ 代碼清楚地分開,還避免了重復(fù)輸入 __asm 關(guān)鍵字,因此推薦使用第一種方法。

?

??? 不像在 C/C++ 中的“{}”,__asm 塊的“{}”不會影響 C/C++ 變量的作用范圍。同時,__asm 塊可以嵌套,而且嵌套也不會影響變量的作用范圍。

?

??? 為了與低版本的 Visual C++ 兼容,_asm 和 __asm 具有相同的意義。另外,Visual C++ 支持標準 C++ 的 asm 關(guān)鍵字,但是它不會生成任何指令,它的作用僅限于使編譯器不會出現(xiàn)編譯錯誤。要使用內(nèi)聯(lián)匯編,必須使用 __asm 而不是 asm 關(guān)鍵字。

?

?

三、 匯編語言
?

1. 指令集
?

??? 內(nèi)聯(lián)匯編支持 Intel Pentium 4 和 AMD Athlon 的所有指令。更多其它處理器的指令可以通過 _EMIT 偽指令來創(chuàng)建(_EMIT 偽指令說明見下文)。

?

2. MASM 表達式
?

??? 在內(nèi)聯(lián)匯編代碼中,可以使用所有的 MASM 表達式(MASM 表達式是指用來計算一個數(shù)值或一個地址的操作符和操作數(shù)的組合)。

?

3. 數(shù)據(jù)指示符和操作符
?

??? 雖然 __asm 塊中允許使用 C/C++ 的數(shù)據(jù)類型和對象,但它不能使用 MASM 指示符和操作符來定義數(shù)據(jù)對象。這里特別指出,__asm 塊中不允許 MASM 中的定義指示符(DB、DW、DD、DQ、DT 和 DF),也不允許使用 DUP 和 THIS 操作符。MASM 中的結(jié)構(gòu)和記錄也不再有效,內(nèi)聯(lián)匯編不接受 STRUC、RECORD、WIDTH 或者 MASK。

?

4. EVEN 和 ALIGN 指示符
?

??? 盡管內(nèi)聯(lián)匯編不支持大多數(shù) MASM 指示符,但它支持 EVEN 和 ALIGN。當需要的時候,這些指示符在匯編代碼里面加入 NOP 指令(空操作)使標號對齊到特定邊界。這樣可以使某些處理器取指令時具有更高的效率。

?

5. MASM 宏指示符
?

??? 內(nèi)聯(lián)匯編不是宏匯編,不能使用 MASM 宏指示符(MACRO、REPT、IRC、IRP 和 ENDM)和宏操作符(<>、!、&、% 和 .TYPE)。

?

6. 段
?

??? 必須使用寄存器而不是名稱來指明段(段名稱“_TEXT”是無效的)。并且,段跨越必須顯式地說明,如 ES:[EBX]。

?

7. 類型和變量大小
?

??? 在內(nèi)聯(lián)匯編中,可以用 LENGTH、SIZE 和 TYPE 來獲取 C/C++ 變量和類型的大小。

?

l?????? LENGTH 操作符用來取得 C/C++ 中數(shù)組的元素個數(shù)(如果不是一個數(shù)組,則結(jié)果為 1)。

l?????? SIZE 操作符可以獲取 C/C++ 變量的大小(一個變量的大小是 LENGTH 和 TYPE 的乘積)。

l?????? TYPE 操作符可以返回 C/C++ 類型和變量的大小(如果變量是一個數(shù)組,它得到的是數(shù)組中單個元素的大小)。

?

??? 例如,程序中定義了一個 8 維的整數(shù)型變量:

?

??????? int iArray[8];

?

??? 下面是 C 和匯編表達式中得到的 iArray 及其元素的相關(guān)值:

?

__asm
?C
?Size
?
LENGTH iArray
?sizeof(iArray)/sizeof(iArray[0])
?8
?
SIZE iArray
?sizeof(iArray)
?32
?
TYPE iArray
?sizeof(iArray[0])
?4
?


?

8. 注釋
?

??? 內(nèi)聯(lián)匯編中可以使用匯編語言的注釋,即“;”。例如:

?

??????? __asm MOV EAX, OFFSET pbBuff? ; Load address of pbBuff

?

??? 因為 C/C++ 宏將會展開到一個邏輯行中,為了避免在宏中使用匯編語言注釋帶來的混亂,內(nèi)聯(lián)匯編也允許使用 C/C++ 風格的注釋。

?

9. _EMIT 偽指令
?

??? _EMIT 偽指令相當于 MASM 中的 DB,但是 _EMIT 一次只能在當前代碼段(.text 段)中定義一個字節(jié)。例如:

?

??????? __asm

??????? {

??????????? JMP _CodeLabel

?

??????????? _EMIT 0x00??????? ; 定義混合在代碼段的數(shù)據(jù)

??????????? _EMIT 0x01

?

??????? _CodeLabel:??????????? ; 這里是代碼

??????????? _EMIT 0x90??????? ; NOP指令

??????? }

?

10. 寄存器使用
?

??? 一般來說,不能假定某個寄存器在 __asm 塊開始的時候有已知的值。寄存器的值將不能保證會從 __asm 塊保留到另外一個 __asm 塊中。

?

??? 如果一個函數(shù)聲明為 __fastcall 調(diào)用方式,則其參數(shù)將通過寄存器而不是堆棧來傳遞。這將會使 __asm 塊產(chǎn)生問題,因為函數(shù)無法被告知哪個參數(shù)在哪個寄存器中。如果函數(shù)接收了 EAX 中的參數(shù)并立即儲存一個值到 EAX 中的話,原來的參數(shù)將丟失掉。另外,在所有聲明為 __fastcall 的函數(shù)中,ECX 寄存器是必須一直保留的。為了避免以上的沖突,包含 __asm 塊的函數(shù)不要聲明為 __fastcall 調(diào)用方式。

?

??? * 提示:如果使用 EAX、EBX、ECX、EDX、ESI 和 EDI 寄存器,你不需要保存它。但如果你用到了 DS、SS、SP、BP 和標志寄存器,那就應(yīng)該用 PUSH 保存這些寄存器。

?

??? * 提示:如果程序中改變了用于 STD 和 CLD 的方向標志,必須將其恢復(fù)到原來的值。

?

?

四、 使用 C/C++ 元素
?

1. 可用的 C/C++ 元素
?

??? C/C++ 與匯編語言可以混合使用,在內(nèi)聯(lián)匯編中可以使用 C/C++ 變量以及很多其它的 C/C++ 元素,包括:

?

l?????? 符號,包括標號、變量和函數(shù)名;

l?????? 常量,包括符號常量和枚舉型成員;

l?????? 宏定義和預(yù)處理指示符;

l?????? 注釋,包括“/**/”和“//”;

l?????? 類型名,包括所有 MASM 中合法的類型;

l?????? typedef 名稱,通常使用 PTR 和 TYPE 操作符,或者使用指定的的結(jié)構(gòu)或枚舉成員。

?

??? 在內(nèi)聯(lián)匯編中,可以使用 C/C++ 或匯編語言的基數(shù)計數(shù)法。例如,0x100 和 100H 是相等的。

?

2. 操作符使用
?

??? 內(nèi)聯(lián)匯編中不能使用諸如“<<”一類的 C/C++ 操作符。但是,C/C++ 和 MASM 共有的操作符(比如“*”和“[]”操作符),都被認為是匯編語言的操作符,是可以使用的。舉個例子:

?

??????? int iArray[10];

?

??????? __asm MOV iArray[6], BX?????????? ; Store BX at iArray + 6 (Not scaled)

??????? iArray[6] = 0;????????????????????? // Store 0 at iArray+12 (Scaled)

?

??? * 提示:在內(nèi)聯(lián)匯編中,可以使用 TYPE 操作符使其與 C/C++ 一致。比如,下面兩條語句是一樣的:

?

??????? __asm MOV iArray[6 * TYPE int], 0?? ; Store 0 at iArray + 12

??????? iArray[6] = 0;????????????????????? // Store 0 at iArray + 12

?

3. C/C++ 符號使用
?

??? 在 __asm 塊中可以引用所有在作用范圍內(nèi)的 C/C++ 符號,包括變量名稱、函數(shù)名稱和標號。但是不能訪問 C++ 類的成員函數(shù)。

?

??? 下面是在內(nèi)聯(lián)匯編中使用 C/C++ 符號的一些限制:

?

l?????? 每條匯編語句只能包含一個 C/C++ 符號。在一條匯編指令中,多個符號只能出現(xiàn)在 LENGTH、TYPE 或 SIZE 表達式中。

l?????? 在 __asm 塊中引用函數(shù)必須先聲明。否則,編譯器將不能區(qū)別 __asm 塊中的函數(shù)名和標號。

l?????? 在 __asm 塊中不能使用對于 MASM 來說是保留字的 C/C++ 符號(不區(qū)分大小寫)。MASM 保留字包含指令名稱(如 PUSH)和寄存器名稱(如 ESI)等。

l?????? 在 __asm 塊中不能識別結(jié)構(gòu)和聯(lián)合標簽。

?

4. 訪問 C/C++ 中的數(shù)據(jù)
?

??? 內(nèi)聯(lián)匯編的一個非常大的方便之處是它可以使用名稱來引用 C/C++ 變量。例如,如果 C/C++ 變量 iVar 在作用范圍內(nèi):

?

??????? __asm MOV EAX, iVar? ; Stores the value of iVar in EAX

?

??? 如果 C/C++ 中的類、結(jié)構(gòu)或者枚舉成員具有唯一的名稱,則在 __asm 塊中可以只通過成員名稱來訪問(省略“.”操作符之前的變量名或 typedef 名稱)。然而,如果成員不是唯一的,你必須在“.”操作符之前加上變量名或 typedef 名稱。例如,下面的兩個結(jié)構(gòu)都具有 SameName 這個成員變量:

?

??????? struct FIRST_TYPE

??????? {

??????????? char *pszWeasel;

??????????? int SameName;

??????? };

?

??????? struct SECOND_TYPE

??????? {

??????????? int iWonton;

??????????? long SameName;

??????? };

?

??? 如果按下面方式聲明變量:

?

??????? struct FIRST_TYPE ftTest;

??????? struct SECOND_TYPE stTemp;

?

??? 那么,所有引用 SameName 成員的地方都必須使用變量名,因為 SameName 不是唯一的。另外,由于上面的 pszWeasel 變量具有唯一的名稱,你可以僅僅使用它的成員名稱來引用它:

?

??????? __asm

??????? {

??????????? MOV EBX, OFFSET ftTest

??????????? MOV ECX, [EBX]ftTest.SameName???? ; 必須使用“ftTest”

??????????? MOV ESI, [EBX]. pszWeasel?????????? ; 可以省略“ftTest”

??????? }

?

??? * 提示:省略變量名僅僅是為了書寫代碼方便,生成的匯編指令還是一樣的。

?

5. 用內(nèi)聯(lián)匯編寫函數(shù)
?

??? 如果用內(nèi)聯(lián)匯編寫函數(shù)的話,要傳遞參數(shù)和返回一個值都是非常容易的。看下面的例子,比較一下用獨立匯編和內(nèi)聯(lián)匯編寫的函數(shù):

?

??????? ; PowerAsm.asm

??????? ; Compute the power of an integer

?

??????? PUBLIC????? GetPowerAsm

??????? _TEXT?????? SEGMENT WORD PUBLIC ’CODE’

??????? GetPowerAsm PROC

??????????? PUSH??? EBP???????????? ; Save EBP

??????????? MOV???? EBP, ESP??????? ; Move ESP into EBP so we can refer

????????????????????????????????????? ; to arguments on the stack

??????????? MOV???? EAX, [EBP+4]??? ; Get first argument

??????????? MOV???? ECX, [EBP+6]??? ; Get second argument

??????????? SHL???? EAX, CL???????? ; EAX = EAX * (2 ^ CL)

??????????? POP???? EBP???????????? ; Restore EBP

??????????? RET???????????????????? ; Return with sum in EAX

??????? GetPowerAsm ENDP

??????? _TEXT?????? ENDS

??????????????????? END

?

??? C/C++ 函數(shù)一般用堆棧來傳遞參數(shù),所以上面的函數(shù)中需要通過堆棧位置來訪問它的參數(shù)(在 MASM 或其它一些匯編工具中,也允許通過名稱來訪問堆棧參數(shù)和局部堆棧變量)。

?

??? 下面的程序是使用內(nèi)聯(lián)匯編寫的:

?

??????? // PowerC.c

?

??????? #include <Stdio.h>

?

??????? int GetPowerC(int iNum, int iPower);

?

??????? int main()

??????? {

??????????? printf("3 times 2 to the power of 5 is %dn", GetPowerC( 3, 5));

??????? }

?

??????? int GetPowerC(int iNum, int iPower)

??????? {

??????????? __asm

??????????? {

??????????????? MOV EAX, iNum?? ; Get first argument

??????????????? MOV ECX, iPower? ; Get second argument

??????????????? SHL EAX, CL????? ; EAX = EAX * (2 to the power of CL)

??????????? }

??????????? // Return with result in EAX

??????? }

?

??? 使用內(nèi)聯(lián)匯編寫的 GetPowerC 函數(shù)可以通過參數(shù)名稱來引用它的參數(shù)。由于 GetPowerC 函數(shù)沒有執(zhí)行 C 的 return 語句,所以編譯器會給出一個警告信息,我們可以通過 #pragma warning 禁止生成這個警告。

?

??? 內(nèi)聯(lián)匯編的其中一個用途是編寫 naked 函數(shù)的初始化和結(jié)束代碼。對于一般的函數(shù),編譯器會自動幫我們生成函數(shù)的初始化(構(gòu)建參數(shù)指針和分配局部變量等)和結(jié)束代碼(平衡堆棧和返回一個值等)。使用內(nèi)聯(lián)匯編,我們可以自己編寫干干凈凈的函數(shù)。當然,此時我們必須自己動手做一些有關(guān)函數(shù)初始化和掃尾的工作。例如:

?

??????? void __declspec(naked) MyNakedFunction()

??????? {

??????????? // Naked functions must provide their own prolog.

??????????? __asm

??????????? {

??????????????? PUSH EBP

??????????????? MOV ESP, EBP

??????????????? SUB ESP, __LOCAL_SIZE

??????????? }

?

??????????? .

??????????? .

??????????? .

?

??????????? // And we must provide epilog.

??????????? __asm

??????????? {

??????????????? POP EBP

??????????????? RET

??????????? }

??????? }

?

6. 調(diào)用 C/C++ 函數(shù)
?

??? 內(nèi)聯(lián)匯編中調(diào)用聲明為 __cdecl 方式(默認)的 C/C++ 函數(shù)必須由調(diào)用者清除參數(shù)堆棧,下面是一個調(diào)用 C/C++ 函數(shù)例子:

?

??????? #include <Stdio.h>

?

??????? char szFormat[] = "%s %sn";

??????? char szHello[] = "Hello";

??????? char szWorld[] = " world";

?

??????? void main()

??????? {

??????????? __asm

??????????? {

??????????????? MOV???? EAX, OFFSET szWorld

??????????????? PUSH??? EAX

??????????????? MOV???? EAX, OFFSET szHello

??????????????? PUSH??? EAX

??????????????? MOV???? EAX, OFFSET szFormat

??????????????? PUSH??? EAX

??????????????? CALL??? printf

?

??????????????? // 壓入了 3 個參數(shù)在堆棧中,調(diào)用函數(shù)之后要調(diào)整堆棧

??????????????? ADD???? ESP, 12

??????????? }

??????? }

?

??? * 提示:參數(shù)是按從右往左的順序壓入堆棧的。

?

??? 如果調(diào)用 __stdcall 方式的函數(shù),則不需要自己清除堆棧。因為這種函數(shù)的返回指令是 RET n,會自動清除堆棧。大多數(shù) Windows API 函數(shù)均為 __stdcall 調(diào)用方式(僅除 wsprintf 等幾個之外),下面是一個調(diào)用 MessageBox 函數(shù)的例子:

?

??????? #include <Windows.h>

?

??????? TCHAR g_tszAppName[] = TEXT("API Test");

?

??????? void main()

??????? {

??????????? TCHAR tszHello[] = TEXT("Hello, world!");

?

??????????? __asm

??????????? {

??????????????? PUSH??? MB_OK OR MB_ICONINFORMATION

??????????????? PUSH??? OFFSET g_tszAppName????? ; 全局變量用 OFFSET

??????????????? LEA???? EAX, tszHello?????????????? ; 局部變量用 LEA

??????????????? PUSH??? EAX

??????????????? PUSH??? 0

?

; 注意這里不是 CALL MessageBox,而是調(diào)用重定位過的函數(shù)地址

??????????????? CALL??? DWORD PTR [MessageBox]

??????????? }

??????? }

?

??? * 提示:可以不受限制地訪問 C++ 成員變量,但是不能訪問 C++ 的成員函數(shù)。

?

7. 定義 __asm 塊為 C/C++ 宏
?

??? 使用? C/C++ 宏可以方便地把匯編代碼插入到源代碼中。但是這其中需要額外地注意,因為宏將會擴展到一個邏輯行中。為了不會出現(xiàn)問題,請按以下規(guī)則編寫宏:

?

l?????? 使用花括號把 __asm 塊包圍住;

l?????? 把 __asm 關(guān)鍵字放在每條匯編指令之前;

l?????? 使用經(jīng)典 C 風格的注釋(“/* comment */”),不要使用匯編風格的注釋(“; comment”)或單行的 C/C++ 注釋(“// comment”);

?

??? 舉個例子,下面定義了一個簡單的宏:

?

??????? #define PORTIO __asm????????

??????? /* Port output */??????????????

??????? {??????????????????????????

??????????? __asm MOV AL, 2????????

??????????? __asm MOV DX, 0xD007??

??????????? __asm OUT DX, AL???????

??????? }

?

??? 乍一看來,后面的三個 __asm 關(guān)鍵字好像是多余的。其實它們是需要的,因為宏將被擴展到一個單行中:

?

??????? __asm /* Port output */ {__asm MOV AL, 2? __asm MOV DX, 0xD007? __asm OUT DX, AL}

?

??? 從擴展后的代碼中可以看出,第三個和第四個 __asm 關(guān)鍵字是必須的(作為語句分隔符)。在 __asm 塊中,只有 __asm 關(guān)鍵字和換行符會被認為是語句分隔符,又因為定義為宏的一個語句塊會被認為是一個邏輯行,所以必須在每條指令之前使用 __asm 關(guān)鍵字。

?

??? 括號也是需要的,如果省略了它,編譯器將不知道匯編代碼在哪里結(jié)束,__asm 塊后面的 C/C++ 語句看起來會被認為是匯編指令。

?

??? 同樣是由于宏展開的原因,匯編風格的注釋(“; comment”)和單行的 C/C++ 注釋(“// commen”)也可能會出現(xiàn)錯誤。為了避免這些錯誤,在定義 __asm 塊為宏時請使用經(jīng)典 C 風格的注釋(“/* comment */”)。

?

??? 和 C/C++ 宏一樣 __asm 塊寫的宏也可以擁有參數(shù)。和 C/C++ 宏不一樣的是,__asm 宏不能返回一個值,因此,不能使用這種宏作為 C/C++ 表達式。

?

??? 不要不加選擇地調(diào)用這種類型的宏。比如,在聲明為 __fastcall 的函數(shù)中調(diào)用匯編語言宏可能會導(dǎo)致不可預(yù)料的結(jié)果(請參看前文的說明)。

?

8. 轉(zhuǎn)跳

?

??? 可以在 C/C++ 里面使用 goto 轉(zhuǎn)跳到 __asm 塊中的標號處,也可以在 __asm 塊中轉(zhuǎn)跳到 __asm 塊里面或外面的標號處。__asm 塊內(nèi)的標號是不區(qū)分大小寫的(指令、指示符等也是不區(qū)分大小寫的)。例如:

?

??????? void MyFunction()

??????? {

??????????? goto C_Dest;??? /* 正確 */

??????????? goto c_dest;???? /* 錯誤 */

?

??????????? goto A_Dest;??? /* 正確 */

??????????? goto a_dest;???? /* 正確 */

?

??????????? __asm

??????????? {

??????????????? JMP C_Dest? ; 正確

??????????????? JMP c_dest?? ; 錯誤

?

??????????????? JMP A_Dest? ; 正確

??????????????? JMP a_dest?? ; 正確

?

??????? a_dest:?????????????? ; __asm 標號

??????????? }

?

??????? C_Dest:????????????? /* C/C++ 標號 */

??????????? return;

??????? }

?

??? 不要使用函數(shù)名稱當作標號,否則將轉(zhuǎn)跳到函數(shù)中執(zhí)行,而不是標號處。例如,由于 exit 是 C/C++ 的函數(shù),下面的轉(zhuǎn)跳將不會到 exit 標號處:

?

??????? ; 錯誤:使用函數(shù)名作為標號

??????? JNE exit

??????? .

??????? .

??????? .

??????? exit:

??????? .

??????? .

??????? .

?

??? 美元符號“$”用于指定當前指令位置,常用于條件跳轉(zhuǎn)中,例如:

?

??????? JNE $+5????? ; 下面這條指令的長度是 5 個字節(jié)

??????? JMP _Label

??????? NOP???????? ; $+5,轉(zhuǎn)跳到了這里

??????? .

??????? .

??????? .

??????? _Label:

??????? .

??????? .

??????? .

?

?

五、在 Visual C++ 工程中使用獨立匯編
?

??? 內(nèi)聯(lián)匯編代碼不易于移植,如果你的程序打算在不同類型的機器(比如 x86 和 Alpha)上運行,你可能需要在不同的模塊中使用特定的機器代碼。這時候你可以使用 MASM(Microsoft Macro Assembler),因為 MASM 支持更多方便的宏指令和數(shù)據(jù)指示符。

?

??? 這里簡單介紹一下在 Visual Studio .NET 2003 中調(diào)用 MASM 編譯獨立匯編文件的步驟。

?

??? 在 Visual C++ 工程中,添加按 MASM 的要求編寫的 .asm 文件。在解決方案資源管理器中,右擊這個文件,選擇“屬性”菜單項,在屬性對話框中,點擊“自定義生成步驟”,設(shè)置如下項目:

?

??? 命令行:ML.exe /nologo /c /coff "-Fo$(IntDir)$(InputName).obj" "$(InputPath)"

??? 輸出:$(IntDir)$(InputName).obj

?

??? 如果要生成調(diào)試信息,可以在命令行中加入“/Zi”參數(shù),還可以根據(jù)需要生成 .lst 和 .sbr 文件。

?

??? 如果要在匯編文件中調(diào)用 Windows API,可以從網(wǎng)上下載 MASM32 包(包含了 MASM 匯編工具、非常完整的 Windows API 頭文件/庫文件、實用宏以及大量的 Win32 匯編例子等)。相應(yīng)地,應(yīng)該在命令行中加入“/I X:MASM32INCLUDE”參數(shù)指定 Windows API 匯編頭文件(.inc)的路徑。MASM32 的主頁是:http://www.masm32.com,里面可以下載最新版本的 MASM32 包。

?

總結(jié)

以上是生活随笔為你收集整理的在 Visual C++ 中使用内联汇编的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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