x86平台轉x64平台關於內聯匯編不再支持的解決


x86平台轉x64平台關於內聯匯編不再支持的解決

 

 

2011/08/25   把自己碰到的問題以及解決方法給記錄下來,留着備用!

 

工具:VS2005  編譯器:cl.exe(X86 C/C++)  ml64.exe(X64 ASM64)

前提:X86下內聯匯編是嵌在函數當中實現的

 

X86平台下,可以輕松的在C/C++代碼中嵌入匯編代碼,稱其為“內聯匯編”,使用”__asm{}”語法即可,比較簡單,這里不做介紹。當你在X86平台下,由於性能和速度的要求,需要在C/C++代碼中內聯匯編。而當你好不容易在X86平台下實現了這些以后,發現要轉到X64平台下面,怎么辦(不是說在X64下運行X86的程序,因為這是肯定可以的,而是說從X86工程轉到X64工程)?可以兼容的吧?先試試再說嘛。

 

試一試:

x86平台轉x64平台關於內聯匯編不再支持的解決

 

看到上圖的DebugWin32字眼么,就從這里開始改。

 

 

下拉Win32右端的下三角,呈現出如上圖。由於我已經設置好了,會有x64字眼。如果以前沒有設置,那么默認是沒有x64字樣的。要出現x64平台,請設置:點擊“配置管理器”,一系列操作見圖知意:

 x86平台轉x64平台關於內聯匯編不再支持的解決

注意:一般情況下,是在X86平台下編程,至少我是這樣的。那么裝VS2005的時候默認是不支持在X86平台下編譯連接生成X64平台的EXE的。如果真的要在X86下編譯連接生成X64平台的EXE,比如和我一樣。那么找到您安裝VS2005時候的SETUP.EXE,雙擊它,選擇“添加或者刪除”選項(名字不確定,但是是第一項),然后勾選住有X64字眼的那一項(具體我也不記得了),然后等SETUP.EXE幫你裝上這一項就好了。接下來看圖~

 

 x86平台轉x64平台關於內聯匯編不再支持的解決

 

 

 

 

x86平台轉x64平台關於內聯匯編不再支持的解決

 

 
x86平台轉x64平台關於內聯匯編不再支持的解決

 

 

注意:當你第一次“新建”的時候,在“新建平台(P)”下會出現“X64”選項,這里沒有出現,因為我之前已經都設置好了。

 x86平台轉x64平台關於內聯匯編不再支持的解決

 

x86平台轉x64平台關於內聯匯編不再支持的解決


 

 

都說了試一試了,結果上面才弄好了環境設置。下面編譯連接(F7),啊哦!出錯了,而且一大堆錯誤提示!媽呀!!!

 

經典的一句報錯是:

error C4235: 使用了非標准擴展: 不支持在此結構上使用“__asm”關鍵字

 

完蛋了!想辦法咯~

上網求解方案,說VS2005 X64平台下不再支持內聯匯編了!但是考慮到時間,又不允許換編譯器,怎么辦?繼續上網搜索解決方法。。。有了。單獨寫匯編ASM文件,編譯生成.OBJ文件。也就是說不能在C/C++代碼中直接內嵌(內聯)匯編了,而要把原先內聯的匯編全都放在一個獨立的匯編文件中。換句話說,一部分匯編代碼,一部分C/C++代碼。然后將獨立匯編編譯生成的.OBJ文件附加到C/C++主工程之中。。。好像好難哦,沒事,萬事開頭難嘛~

好的,不懂的話先往下看了!

下面還有一些頭大的操作那

記住,我是在X86平台下編譯連接X64平台下的程序哦!主工程是在X64平台下運行的程序。上面說的兩部分:匯編和C/C++當然是X64平台下的(肯定的嘛)

64位匯編,傻眼了,32位都頭大,一下子跳到64位,有沒有搞錯??沒有,32位匯編代碼應該是不用做太大的改動的。事實上證明,確實是這樣的哦~

首先,不是把原先的內聯匯編代碼改成單獨的匯編文件。問題是寫好了64位匯編,怎么編譯單獨的匯編文件?用VS2005集成環境去編譯單獨的匯編文件,對,就是這樣,不要再回到DOS界面敲命令行了,這會死人的,而且不方便!!接下來跟着我做:

VS2005建立一個常規的空項目。然后將自己改好的64位匯編(說白了,大部分還是32位的指令)加入該工程中,F7編譯連接好像有反應,但是是假象!默認的話IDE不認識匯編。怎么辦?

 

x86平台轉x64平台關於內聯匯編不再支持的解決 

  

  

點擊“自定義生成規則”:

 

 x86平台轉x64平台關於內聯匯編不再支持的解決

 

默認只有前兩項,最后一項是我自己添加的。第一項,我不知道什么東西。第二項是32匯編的編譯器(ml.exe)。但是我們是要編譯64位匯編啊!不急,按着下面做:

找到這個路徑“…\Program Files\Microsoft Visual Studio 8\VC\VCProjectDefaults”,OK,在這個目錄下,找到masm.rules。接下來,復制粘貼masm.rules,改復制文件名字為“masm64.rules”。

回到IDE,上面就有了三項了。對最后一項進行修改,明顯的,不然后兩項是一樣的。勾選第三項,點擊“修改規則文件”:

 

 

 x86平台轉x64平台關於內聯匯編不再支持的解決

 點擊“修改生成規則”:

x86平台轉x64平台關於內聯匯編不再支持的解決

 

改成藍色選中的文字就行了,就是簡單的加了“64”在原先ml后面,你懂的~一路確定,萬事搞定!如果64位匯編文件沒有語法錯誤,就會生成.OBJ文件了,哈哈!沒有這么簡單的啦。。。主要是編寫符合要求的64位匯編代碼,而不是以前簡單的內聯在C/C++代碼中。關於編寫單獨匯編代碼文件,靠你原先的匯編基礎了,這個我沒話說了,靠你們自己了!!

OK,“搞定了”,F7如下提示:

 

1>------ 已啟動生成: 項目: ASM64, 配置: Debug x64 ------

1>正在鏈接...

1>LINK : fatal error LNK1561: 必須定義入口點

1>生成日志保存在“file://f:\VC Projects\Visual Studio 2005 Projects\happyway\test\ASM64\ASM64\x64\Debug\BuildLog.htm

1>ASM64 - 1 個錯誤,個警告

========== 生成: 0 已成功, 1 已失敗, 0 最新, 0 已跳過==========

 

 

 

我沒有去深究入口點,因為我不需要這個,入口點在C/C++主工程那,匯編搞定,語法上!得到了編譯生成的asm64.obj

接下來,是另一部分,C/C++主工程代碼了,停筆,和田大頭吃飯去~

……

X,田大頭放我鴿子,一個人吃飯!

 

注意,X86下內聯匯編是嵌在函數當中實現的,所以上面的64位匯編的任務就是編寫函數過程(PROC)

接下來,回到主工程。在主工程中要用到匯編中的函數,那么匯編生成的.OBJ文件就派上用場了。主工程可以調用.OBJ去使用匯編中的函數。過程如下:

“項目”->“屬性”,彈出:

然后“配置屬性”->”鏈接器”->“輸入”,,右側的“附加依賴項”中,填入匯編文件生成的.OBJ,如下圖。

x86平台轉x64平台關於內聯匯編不再支持的解決

 

然后暴露出匯編中編寫好的函數的接口。

我是這樣暴露我的匯編函數的:

extern "C" int __stdcall  RGB2YUV_ALL(int bmpWidth, int bmpHeight, unsigned char *videoRef, unsigned char *YUVData);

extern "C" int __stdcall  RGB2YUV_BLOCK(int bmpWidth, int bmpHeight, unsigned char *videoRef, unsigned char *YUVData, int LargebmpWidth);

如果一切順利的話,主工程就可以使用上面的函數,編譯連接都沒有問題,但是萬惡的運行時有錯,那就得靠你的調試了!至此,差不多,從X86X64,從內聯匯編到單獨的匯編文件,解決了X64下不支持內聯匯編的問題啦,嘻嘻。

但是,更加辛苦和耗時的是匯編代碼的修改和編寫、C/C++調用匯編函數過程遇到的種種問題,但是只要努力再加上有一定基礎的情況下是搞得定許多問題的!

如果你感興趣,或者就是和我一樣碰到這樣的問題,下面給出實例代碼。

1. ASM文件

.data

;數據段


.code
 FUNC proc 
 MOV EAX, 1234
 RET 
 FUNC endp
end

 

2.測試VS2005控制台工程

#include <stdio.h>

extern "C" int __stdcall  FUNC();

 

int main(int argc, WCHAR* argv[])

{

 

    int nret = FUNC();

    printf(“%d\n”, nret);

    system("pause");  

    return 0;

}

 

這其中的過程,還有很多需要解決的問題和思考的地方,這需要你的基本功了,就不在這里都說出來了,做一做就都知道了!相信自己!

 jpg改rar

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM