x86平台转x64平台关于内联汇编不再支持的解决_javax86改x64-程序员宅基地

技术标签: C  

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 bmpWidthint bmpHeightunsigned char *videoRefunsigned char*YUVData);

extern "C" int __stdcall  RGB2YUV_BLOCK(int bmpWidthint bmpHeightunsigned char *videoRefunsigned char*YUVDataint 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;

}

 

这其中的过程,还有很多需要解决的问题和思考的地方,这需要你的基本功了,就不在这里都说出来了,做一做就都知道了!相信自己!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ayang1986/article/details/82885170

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签