VS2005混合编译ARM汇编代码-转
原文地址:http://blog.csdn.net/annelcf/article/details/5468093
公司HW team有人希望可以给他们写一个在WinCE上,单独读写DDR的工具,以方便他们量测Memory读写时的硬件信号。
在开发过程中,发现简单的在Storage Memory区域拷贝或粘贴文件不能达到硬件量测的要求,需要直接通过编写ARM汇编指令让CPU直接对Memory进行读写数据。
以 前没有用VS2005编写过汇编代码,所以走了点弯路,一直试图用内嵌汇编的方式来build,可恨的VS2005死活不认ARM指令,后来请出 google大神一搜,原来这条路已经有很多先行者试过了,结论是VS2005不能用内嵌汇编的方式build ARM汇编代码!
俗话说的好啊,机器是死的,人是活的!
google大神给我指出了一条通向光明的道路: VS2005中是可以对纯粹的arm汇编文件进行编译的,当然也可以将C编译生成的obj文件和asm汇编文件生成的obj文件进行link。
这种混合编译的方法,网上流传最广的一份代码出自一位叫Larry Bank的老外。
具体方法:
一. 创建编译规则
<?xml version="1.0" encoding="utf-8"?>
<VisualStudioToolFile Name="Arm ASM" Version="8.00">
<Rules>
<CustomBuildRule
Name="Arm asm" DisplayName="Arm asm"
CommandLine="armasm -o "$(IntDir)/$(InputName).obj" [$Inputs] "
Outputs="$(IntDir)/$(InputName).obj"
FileExtensions="*.asm"
ExecutionDescription="Executing tool..."
>
<Properties></Properties>
</CustomBuildRule>
</Rules>
</VisualStudioToolFile>
将上面的代码复制到记事本中,并将其保存到vs2005安装目录的Microsoft Visual Studio 8/VC/VCProjectDefaults文件夹下,命名为armcc.rules
二. 在VS2005中添加编译规则
选择需要和ARM汇编代码做混合编译的Project,右键弹出的菜单中选择"Custom Build Rules...”,在弹出的对话框中点"Find Existing..."按钮,选择armcc.rules文件
三. 编写ARM汇编代码,并将其加入VS2005的Project中(以Larry Bank的code为例)
ARM汇编代码,文件命名为armtest.asm:
; TITLE("Sample App")
;++
AREA sample, CODE, READONLY ; name this block of code
EXPORT TEST
IMPORT iGlobal
;
; Called from C as int ARMTEST1(int, int, int, int);
; The first 4 parameters are passed in r0-r3, more parameters would be passed on the stack
;
TEST proc
add r0,r0,r1 ; add all of the inputs together
add r0,r0,r2
add r0,r0,r3
ldr r1,=iGlobal ; get the value of our global variable
ldr r1,[r1] ; dereference the pointer (I know there's
a pipe stall here)
add r0,r0,r1
; we're not concerned with performance in this example
mov pc,lr ; return to C with the value in R0
endp
LTORG ; allow room for the address constant of our global
(loaded relative to PC)
END
将armtest.asm加入VS2005的Project中,编写调用代码:
// Windows CE Sample Application
// File Name: MAIN.C
// Demonstrations how to use ARM assembly language within a C program
// Written by Larry Bank 3/25/2007
#include <windows.h>
int iGlobal;
int TEST(int, int, int , int);
/****************************************************************************
* *
* FUNCTION : WinMain(HANDLE, HANDLE, LPSTR, int) *
* *
* PURPOSE : Program entrypoint *
* *
****************************************************************************/
int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
nCmdShow)
{
int iResult;
TCHAR szTemp[256];
iGlobal = 5;
iResult = TEST(1,2,3,4);
wsprintf(szTemp, L"Result = %d", iResult);
MessageBox(HWND_DESKTOP, szTemp, L"ASM Result", MB_OK);
return 0;
}
/* WinMain() */
四. Build VS2005的Project,当你看到如下信息时,恭喜你~~~你成功了!
========= Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
到这里,可能大家觉得结束了,呵呵,其实才是做了一半!
仔细的朋友可能也发现了,Larry Bank调用armtest.asm中函数的文件MAIN.C在VS2005编译时调用的是C编译器,但是现在很多项目工程会以C++代码编写(*.cpp),在VS2005中会用C++编译器Compile。
如果不注意这点的话,就会出现下面的结果:
error LNK2001: unresolved external symbol iGlobal
error LNK2019: unresolved external symbol "int __cdecl TEST1(int,int,int,int)" (?TEST1@@YAHHHHH@Z)
referenced in function wmain
fatal error LNK1120: 2 unresolved externals
出现这个问题原因是:
汇编源文件再编译以后,函数名称以及变量名称没有做任何的更改,而C++源码在经过C++编译器编译以后,函数名称和变量名称都已经有过变化(可查看编译后的object文件),所以连接的时候会报错。
解决的办法有下列几种:
方法一
将汇编中的函数名称和变量名称都更改为C++编译器编译过的函数名称和变量名称,即?TEST1@@YAHHHHH@Z和?iGlobal@@3HA。注意这种方式在名称前面要加上“|”符号。
; TITLE("Sample App")
;++
AREA armtest, CODE, READONLY ; name this block of code
IMPORT
|?iGlobal@@3HA|
EXPORT |?TEST1@@YAHHHHH@Z|
;
; Called from C as int ARMTEST1(int, int, int, int);
; The first 4 parameters are passed in r0-r3, more parameters would be passed on the stack
;
|?TEST1@@YAHHHHH@Z|
proc
add r0,r0,r1
; add all of the inputs together
add r0,r0,r2
add r0,r0,r3
ldr r1,=iGlobal;|?iGlobal@@3HA| ; get the value of our global variable
ldr r1,[r1] ; dereference the pointer (I know there's a pipe stall here)
add r0,r0,r1 ; we're not concerned with performance in this example
mov pc,lr ; return to C with the value in R0
endp
LTORG
; allow room for the address constant of our global (loaded relative to PC)
END
方法二
在C++源程序中声明变量和函数的时候用extern "C"修饰,直接告诉编译器这是C函数。
extern "C"
{
int iGlobal;
int TEST1(int, int, int , int);
}
VS2005混合编译ARM汇编代码-转的更多相关文章
- 如何在C或C++代码中嵌入ARM汇编代码
转载自:http://blog.csdn.net/roland_sun/article/details/42921131 大家知道,用C或者C++等高级语言编写的程序,会被编译器编译成最终的机器指令. ...
- CentOS7写汇编并编译运行汇编代码
1.下载nasm编译器 下载地址是https://www.nasm.us/pub/nasm/releasebuilds/ wget https://www.nasm.us/pub/nasm/relea ...
- ARM汇编指令调试方法
学习ARM汇编时,少不了对ARM汇编指令的调试.作为支持多语言的调试器,gdb自然是较好的选择.调试器工作时,一般通过修改代码段的内容构造trap软中断指令,实现程序的暂停和程序执行状态的监控.为了在 ...
- 12 ARM汇编
Android系统采用java作为平台软件基础开发语言,NDK使Android平台可以运行C/C++代码这些代码汇编成ARM的elf可执行文件. 原生程序生成过程 经历4步:1.预处理2.编译3.汇编 ...
- GCC 预处理、编译、汇编、链接..
1简介 GCC 的意思也只是 GNU C Compiler 而已.经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言:它现在还支持 Ada 语言.C++ 语言.Java 语言.Objective ...
- 生成ARM汇编
使用ndk即可生成arm汇编 1.首先写好hello.c 2.编写makefile #ndk根目录 NDK_ROOT=E:\Android\android-ndk-r10b #编译器根目录 TOOLC ...
- linux内核分析作业:以一简单C程序为例,分析汇编代码理解计算机如何工作
一.实验 使用gcc –S –o main.s main.c -m32 命令编译成汇编代码,如下代码中的数字请自行修改以防与他人雷同 int g(int x) { return x + 3; } in ...
- 入门 ARM 汇编(一)—— 知识铺垫
我读着史铁生的散文,零碎的牵扯起我生命中不曾出现过的记忆,一如北方的黄山厚土之中悠忽而来的忧伤的信天游,那些灿若信仰一样的阳光以及阳光下虔诚的子民.我想有一次远行,于细碎流淌的时光与路途之中,观察所有 ...
- ARM 汇编指令
ARM汇编程序特点: l 所有运算处理都是发生通用寄存器(一般是R0~R14)的之中.所有存储器空间(如C语言变量的本质就是一个存储器空间上的几个BYTE).的值的处理,都是要传送到通 ...
随机推荐
- vmware 安装提示the msi failed
原因是卸载不干净,使用批处理bat文件卸载,然后重启即可. VMware workstation 10.0序列号:MA491-6NL5Q-AZAM0-ZH0N2-AAJ5A 百度云文件:http:// ...
- 调试MVC项目,不关闭 IIS EXPRESS
在VS主面板打开:工具->选项->调试->编辑继续 取消选中[启用"编辑并继续"] 就OK了 (英文版的请对应相应的操作) 不过这是针对所有的调试,如果你想针 ...
- VBS脚本合集(自制脚本)
一.视频搜索器选择: Selectitem() '######################################### Function Selectitem() 'Set Vedio ...
- cp 覆盖 \cp a test\a
使用cp命令覆盖文件总是提示要输入yes或no,一个两个就算了,大量的文件复制就不行了,即使加上-f参数也无法强行覆盖.苦思冥想不得解,终于在查阅了众多资料后让我找到了解决方法,这里写出来,让有同样困 ...
- Process 'command '/usr/lib/jvm/jdk1.8.0_25/bin/java'' finished with non-zero exit value 2
这个问题有两种可能,第一是jar包或者依赖冲突(版本冲突也算).第二是65535. 对于65535的问题,请看http://blog.csdn.net/t12x3456/article/details ...
- mvc UrlHelper
何谓Helper,其实就是在View中为了实现一些灵活功能而写的方法组. 其实ASP.NET MVC的View是Aspx的页面,本身可以声明定义方法,那为什么要有Helper呢? 其实无非是将界面与逻 ...
- ecshop后台管理显示扩展分类
ecshop 后台商品列表默认只显示分类下的商品,而不显示扩展分类中的商品,以下是我个人给出的解决方法: 打开admin/includes/lib_goods.php 第839行左右的位置 可以看到如 ...
- 解决win7和ubuntu双系统ubuntu不能上网的问题
1.电脑基本配置如下. 我的电脑 戴尔 OptiPlex 9020 Mini Tower操作系统 Windows 7 专业版 64位 SP1 Ubuntu 14.04 2.装系统的过程不再赘述. 可以 ...
- IO模式设置网络编程常见问题总结—IO模式设置,阻塞与非阻塞的比较,recv参数对性能的影响—O_NONBLOCK(open使用)、IPC_NOWAIT(msgrcv)、MSG_DONTWAIT(re
非阻塞IO 和阻塞IO: 在网络编程中对于一个网络句柄会遇到阻塞IO 和非阻塞IO 的概念, 这里对于这两种socket 先做一下说明: 基本概念: 阻塞IO:: socket 的阻塞模式 ...
- C#中的Virtual、Override和new关键词理解
来源:http://blog.csdn.net/jackiezhw/article/details/2673992 在 C# 中,派生类可以包含与基类方法同名的方法. 基类方法必须定义为 virtua ...