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工程)?可以兼容的吧?先试试再说嘛。
试一试:
看到上图的Debug和Win32字眼么,就从这里开始改。
下拉Win32右端的下三角,呈现出如上图。由于我已经设置好了,会有x64字眼。如果以前没有设置,那么默认是没有x64字样的。要出现x64平台,请设置:点击“配置管理器”,一系列操作见图知意:
注意:一般情况下,是在X86平台下编程,至少我是这样的。那么装VS2005的时候默认是不支持在X86平台下编译连接生成X64平台的EXE的。如果真的要在X86下编译连接生成X64平台的EXE,比如和我一样。那么找到您安装VS2005时候的SETUP.EXE,双击它,选择“添加或者删除”选项(名字不确定,但是是第一项),然后勾选住有X64字眼的那一项(具体我也不记得了),然后等SETUP.EXE帮你装上这一项就好了。接下来看图~
注意:当你第一次“新建”的时候,在“新建平台(P)”下会出现“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不认识汇编。怎么办?
点击“自定义生成规则”:
默认只有前两项,最后一项是我自己添加的。第一项,我不知道什么东西。第二项是32汇编的编译器(ml.exe)。但是我们是要编译64位汇编啊!不急,按着下面做:
找到这个路径“…\Program Files\Microsoft Visual Studio
8\VC\VCProjectDefaults”,OK,在这个目录下,找到masm.rules。接下来,复制粘贴masm.rules,改复制文件名字为“masm64.rules”。
回到IDE,上面就有了三项了。对最后一项进行修改,明显的,不然后两项是一样的。勾选第三项,点击“修改规则文件”:
点击“修改生成规则”:
改成蓝色选中的文字就行了,就是简单的加了“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,如下图。
然后暴露出汇编中编写好的函数的接口。
我是这样暴露我的汇编函数的:
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);
如果一切顺利的话,主工程就可以使用上面的函数,编译连接都没有问题,但是万恶的运行时有错,那就得靠你的调试了!至此,差不多,从X86到X64,从内联汇编到单独的汇编文件,解决了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
x86平台转x64平台关于内联汇编不再支持的解决的更多相关文章
- 让Visual Studio x64 支持 __asm内联汇编
目录 让Visual Studio x64 支持 __asm内联汇编 Intel Parallel Studio XE 2016安装 设置Interl C++ Compiler 使VS x64支持内联 ...
- 在Visual C++中使用内联汇编
一.内联汇编的优缺点 因为在Visual C++中使用内联汇编不需要额外的编译器和联接器,且可以处理Visual C++中不能处理的一些事情,而且可以使用在C/C++中的变量,所以非常方便.内联汇编主 ...
- vs编写x64内联汇编
参考自: https://www.cnblogs.com/achillis/p/5369658.html 先转过来, 等实践过了再做相应的修改, hehe 编写涉及系统特性的一些底层程序,特别是She ...
- VS2019解决X64无法内联汇编的问题
策略:VC编译器x64平台不支持内联汇编,我们利用在Source文件中直接添加asm文件,直接在asm文件中写汇编代码,然后将asm文件编译为OBJ文件.然后就可以在c++文件中声明asm文件中的函数 ...
- Linux 中 x86 的内联汇编
工程中需要用到内联汇编,找到一篇不错的文章,趁机学习下. 原文地址:http://www.ibm.com/developerworks/cn/linux/sdk/assemble/inline/ 如果 ...
- C内联汇编
用C写程序比直接用汇编写程序更简洁,可读性更好,但效率可能不如汇编程序,因为C程序毕竟要经由编译器生成汇编代码,尽管现代编译器的优化已经做得很好了,但还是不如手写的汇编代码.另外,有些平台相关的指令必 ...
- C语言的本质(32)——C语言与汇编之C语言内联汇编
用C写程序比直接用汇编写程序更简洁,可读性更好,但效率可能不如汇编程序,因为C程序毕竟要经由编译器生成汇编代码,尽管现代编译器的优化已经做得很好了,但还是不如手写的汇编代码.另外,有些平台相关的指令必 ...
- 最牛X的GCC 内联汇编
导读 正如大家知道的,在C语言中插入汇编语言,其是Linux中使用的基本汇编程序语法.本文将讲解 GCC 提供的内联汇编特性的用途和用法.对于阅读这篇文章,这里只有两个前提要求,很明显,就是 x86 ...
- GCC内联汇编入门
原文为GCC-Inline-Assembly-HOWTO,在google上可以找到原文,欢迎指出翻译错误. 中文版说明 由于译者水平有限,故译文出错之处,还请见谅.C语言的关键字不译,一些单词或词组( ...
随机推荐
- ARM学习 之 如何在向内核写入系统调用
本文主要介绍两个例子:1-系统调用打印“hello kernel” 2-驱动开发板的蜂鸣器 使用的是友善之臂(Friendly ARM)的开发板,三星2440 =================== ...
- 使用 zssh 进行 Zmodem 文件传输
Zmodem 最早是设计用来在串行连接(uart.rs232.rs485)上进行数据传输的,比如,在 minicom 下,我们就可以方便的用 Zmodem (说 sz .rz 可能大家更熟悉)传输文件 ...
- [UML]UML系列——用例图中的各种关系(include、extend)
用例图中的各种关系 一.参与者与用例间的关联关系 参与者与用例之间的通信,也成为关联或通信关系. 二.用例与用例之间的关系 包含关系(include) 扩展关系(extend) 包含关系 (1) 概 ...
- Bash 中的环境变量
在 Bash 里,可以通过 export 命令查看当前 Shell 进程的环境变量,这些环境变量一些是 Bash 自己创建的,还有一些是 Bash 从父进程继承来的,然而需要注意的是,父进程传给 Ba ...
- [译]JavaScript源码转换:非破坏式与再生式
原文:http://ariya.ofilabs.com/2013/06/javascript-source-transformation-non-destructive-vs-regenerative ...
- Linux下如何不停止服务,清空nohup.out文件
tips:最近发现有不少人在百度这个问题,当初如易我也是初学者,随便从网上搜了一下,就转过来了,不过为了避免搜索结果同质化,为大家提供更翔实的参考,我将nohup.out相关知识整理汇总如下: 1.n ...
- There are no resources that can be added or removed from the server
第1步.新建一个“Dynamic Web Project” 第2步.把新建项目里面的.project文件和.settings文件夹复制到导入的那个项目里面. 第3步.把web projiect set ...
- PHP正则表达式详解(三)
1.preg_match() :preg_match() 函数用于进行正则表达式匹配,成功返回 1 ,否则返回 0 . 语法:int preg_match( string pattern, strin ...
- saltstack(主机改名)
已存在salt中的机器,为了规范,需要将这批主机改名 操作流程:在master把这批机器剔除:然修改这批机器的主机名.在/etc/salt目录下.用mv把minion_id和pki的目录重命名.重启s ...
- SpringMVC Controller介绍
SpringMVC Controller 介绍 一.简介 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数据经过业务处理 ...