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 &quot;$(IntDir)/$(InputName).obj&quot; [$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)" ([email protected]@[email protected])
referenced in function wmain
fatal error LNK1120: 2 unresolved externals

出现这个问题原因是:

汇编源文件再编译以后,函数名称以及变量名称没有做任何的更改,而C++源码在经过C++编译器编译以后,函数名称和变量名称都已经有过变化(可查看编译后的object文件),所以连接的时候会报错。

解决的办法有下列几种:

方法一

将汇编中的函数名称和变量名称都更改为C++编译器编译过的函数名称和变量名称,即[email protected]@[email protected]和[email protected]@3HA。注意这种方式在名称前面要加上“|”符号。

;      TITLE("Sample App")
;++
        AREA armtest, CODE, READONLY  ; name this block of code

IMPORT 
|[email protected]@3HA|
    EXPORT  |[email protected]@[email protected]|
;
; 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
;
|[email protected]@[email protected]|
proc
    add r0,r0,r1    
; add all of the inputs together
    add r0,r0,r2
    add r0,r0,r3
    ldr r1,=iGlobal;|[email protected]@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汇编代码-转

时间: 2024-10-12 02:53:54

VS2005混合编译ARM汇编代码-转的相关文章

CentOS7写汇编并编译运行汇编代码

1.下载nasm编译器 下载地址是https://www.nasm.us/pub/nasm/releasebuilds/ wget https://www.nasm.us/pub/nasm/releasebuilds/2.14/nasm-2.14.tar.gz 2.解压安装nasm tar -xvzf nasm-2.14.tar.gz 3.进入到nasm的解压目录中编译并安装nasm cd nasm-2.14 #进入nasm的解压目录 ./configure #配置 make #编译 make

如何实现对ARM汇编指令的调试?

学习ARM汇编语言时,少不了对ARM汇编指令的调试.作为支持多语言的调试器,gdb自然是较好的选择.调试器工作时,一般通过修改代码段的内容构造trap软中断指令,实现程序的暂停和程序执行状态的监控.为了在x86平台上执行ARM指令,可以使用qemu模拟器执行ARM汇编指令,具体的调试方法,一起来看看吧. 一.准备ARM汇编程序 首先,我们构造一段简单的ARM汇编程序作为测试代码main.s. .globl _start _start: mov R0,#0 swi 0x00900001 以上汇编指

通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的

实验一:通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 学号:20135114 姓名:王朝宪 注: 原创作品转载请注明出处   <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 1 1)实验部分(以下命令为实验楼64位Linux虚拟机环境下适用,32位Linux环境可能会稍有不同) 使用 gcc –S –o main.s main.c -m32 命令编译成汇编代码,如下代码中的数字请自行修改以防与

理解计算机的工作方式——通过汇编一个简单的C程序并分析汇编代码

Author: 翁超平 Notice:原创作品转载请注明出处 See also:<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000  本文通过汇编一个简单的C程序,并分析汇编代码,来理解计算机是如何工作的.整个过程都在实验楼上完成,感兴趣的读者可以通过上面给出的课程链接自行动手学习.以下是实验过程和结果. 一.操作步骤 1.首先在通过vim程序建立main.c文件.代码如下: 图1 2.使用如下命令将main.c编

linux 编译C语言代码后产生OBJ文件的方法

如果你不指定编译成什么文件,gcc默认一步到位,直接生成可执行文件你可以试试以下几个参数 -c 只激活预处理,编译,和汇编,也就是他只把程序做成obj文件 例子用法: gcc -c hello.c 他将生成.o的obj文件 -S 只激活预处理和编译,就是指把文件编译成为汇编代码. 例子用法 gcc -S hello.c 他将生成.s的汇编代码,你可以用文本编辑器察看 -E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面. 例子用法: gcc -E hello.c > piano

生成ARM汇编

使用ndk即可生成arm汇编 1.首先写好hello.c 2.编写makefile #ndk根目录 NDK_ROOT=E:\Android\android-ndk-r10b #编译器根目录 TOOLCHAINS_ROOT=$(NDK_ROOT)/toolchains/arm-linux-androideabi-4.6/prebuilt/windows-x86_64 #编译器目录 TOOLCHAINS_PREFIX=$(TOOLCHAINS_ROOT)/bin/arm-linux-androide

C/C++ 中嵌入 arm 汇编

GCC编译器支持直接在C或者C++代码中,嵌入ARM汇编代码.其基本格式非常简单,大致如下: __asm__ [__volatile__] ( assembler template : [output operand list] /* optional */ : [input operand list] /* optional */ : [clobbered register list] /* optional */ ); 首先是关键字“__asm__”,其实也可以写成“asm”.但是“asm”

SDRAM和重定位(二)---开始在汇编代码中调用 C 语言

前面的点亮led的代码由于比较简单,所以全部用汇编代码完成,但是随着代码越来越多,逻辑关系越来越复杂,想要完全用汇编代码来写程序不太现实,必须要借助 c 语言程序,那么就会有从汇编语言到 c 语言的一个过渡阶段. ======================================================= 如何在汇编语言中调用 c 语言? 在汇编中调用 c语言程序的方法很简单,只需利用汇编代码:bl xxx(函数名)即可,但是重点不是如何调用 c 程序,而是汇编代码要为运行 c

预编译,编译,汇编,链接

预编译的文件扩展名是ii gcc -E hello.c -o hello.i 预编译过程主要处理源代码文件当中的以#开头的预编译指令,比如#include就是把头文件插入到这个位置 #define就是把所有的宏定义展开,还有就是删除所有的注释 编译就是把i文件编译成为汇编代码文件,汇编代码扩展名是.s gcc -S hello.i -o hello.s 但是现在版本的gcc把预编译和编译两个步骤合并成为一个步骤, gcc -S hello.c -o hello.s 或者编译器ccl:ccl he