ARM中C和汇编混合编程及示例

发布者:码上奇迹最新更新时间:2011-06-01 关键字:ARM  混合编程 手机看文章 扫描二维码
随时随地手机看文章

参数的传递规则.

根据参数个数是否固定,可以将子程序分为参数个数固定的子程序和参数个数可变的子程序.这两种子程序的参数传递规则是不同的.

1.参数个数可变的子程序参数传递规则

对于参数个数可变的子程序,当参数不超过4个时,可以使用寄存器R0~R3来进行参数传递,当参数超过4个时,还可以使用数据栈来传递参数. 在参数传递时,将所有参数看做是存放在连续的内存单元中的字数据。然后,依次将各名字数据传送到寄存器R0,R1,R2,R3; 如果参数多于4个,将剩余的字数据传送到数据栈中,入栈的顺序与参数顺序相反,即最后一个字数据先入栈. 按照上面的规则,一个浮点数参数可以通过寄存器传递,也可以通过数据栈传递,也可能一半通过寄存器传递,另一半通过数据栈传递.

2.参数个数固定的子程序参数传递规则

对于参数个数固定的子程序,参数传递与参数个数可变的子程序参数传递规则不同,如果系统包含浮点运算的硬件部件,浮点参数将按照下面的规则传递: 各个浮点参数按顺序处理;为每个浮点参数分配FP寄存器;分配的方法是,满足该浮点参数需要的且编号最小的一组连续的FP寄存器.第一个整数参数通过寄存器R0~R3来传递,其他参数通过数据栈传递.

子程序结果返回规则

1.结果为一个32位的整数时,可以通过寄存器R0返回.

2.结果为一个64位整数时,可以通过R0和R1返回,依此类推.

3.结果为一个浮点数时,可以通过浮点运算部件的寄存器f0,d0或者s0来返回.

4.结果为一个复合的浮点数时,可以通过寄存器f0-fN或者d0~dN来返回.

5.对于位数更多的结果,需要通过调用内存来传递.

本文通过几个简单的例子演示了嵌入式开发中常用的C和汇编混合编程的一些方法和基本的思路,其实最核心的问题就是如何在C和汇编之间传值,剩下的问题就是各自用自己的方式来进行处理。

在嵌入式系统开发中,目前使用的主要编程语言是C和汇编,C++已经有相应的编译器,但是现在使用还是比较少的。在稍大规模的嵌入式软件中,例如含有OS,大部分的代码都是用C编写的,主要是因为C语言的结构比较好,便于人的理解,而且有大量的支持库。尽管如此,很多地方还是要用到汇编语言,例如开机时硬件系统的初始化,包括CPU状态的设定,中断的使能,主频的设定,以及RAM的控制参数及初始化,一些中断处理方面也可能涉及汇编。另外一个使用汇编的地方就是一些对性能非常敏感的代码块,这是不能依靠C编译器的生成代码,而要手工编写汇编,达到优化的目的。而且,汇编语言是和CPU的指令集紧密相连的,作为涉及底层的嵌入式系统开发,熟练对应汇编语言的使用也是必须的。
单纯的C或者汇编编程请参考相关的书籍或者手册,这里主要讨论C和汇编的混合编程,包括相互之间的函数调用。下面分四种情况来进行讨论,暂不涉及C++。
1. 在C语言中内嵌汇编
在C中内嵌的汇编指令包含大部分的ARM和Thumb指令,不过其使用与汇编文件中的指令有些不同,存在一些限制,主要有下面几个方面:

a. 不能直接向PC寄存器赋值,程序跳转要使用B或者BL指令
b. 在使用物理寄存器时,不要使用过于复杂的C表达式,避免物理寄存器冲突
c. R12和R13可能被编译器用来存放中间编译结果,计算表达式值时可能将R0到R3、R12及R14用于子程序调用,因此要避免直接使用这些物理寄存器
d. 一般不要直接指定物理寄存器,而让编译器进行分配
内嵌汇编使用的标记是 __asm或者asm关键字,用法如下:
__asm
{
instruction [; instruction]

[instruction]
}
asm(“instruction [; instruction]”);
下面通过一个例子来说明如何在C中内嵌汇编语言,
#include

void my_strcpy(const char *src, char *dest)
{
char ch;

__asm
{
loop:
ldrb ch, [src], #1
strb ch, [dest], #1
cmp ch, #0
bne loop
}
}

int main()
{
char *a = "forget it and move on!";
char b[64];

my_strcpy(a, b);
printf("original: %s", a);
printf("copyed: %s", b);
return 0;
}
在这里C和汇编之间的值传递是用C的指针来实现的,因为指针对应的是地址,所以汇编中也可以访问。

2. 在汇编中使用C定义的全局变量
内嵌汇编不用单独编辑汇编语言文件,比较简洁,但是有诸多限制,当汇编的代码较多时一般放在单独的汇编文件中。这时就需要在汇编和C之间进行一些数据的传递,最简便的办法就是使用全局变量。
/* cfile.c
* 定义全局变量,并作为主调程序
*/

#include
int gVar_1 = 12;
extern asmDouble(void);

int main()
{
printf("original value of gVar_1 is: %d", gVar_1);
asmDouble();
printf(" modified value of gVar_1 is: %d", gVar_1);
return 0;
}
[page]

对应的汇编语言文件
;called by main(in C),to double an integer, a global var defined in C is used.

AREA asmfile, CODE, READONLY

EXPORT asmDouble
IMPORT gVar_1

asmDouble
ldr r0, =gVar_1
ldr r1, [r0]
mov r2, #2
mul r3, r1, r2
str r3, [r0]
mov pc, lr
END

3. 在C中调用汇编的函数
在C中调用汇编文件中的函数,要做的主要工作有两个,一是在C中声明函数原型,并加extern关键字;二是在汇编中用EXPORT导出函数名,并用该函数名作为汇编代码段的标识,最后用mov pc, lr返回。然后,就可以在C中使用该函数了。从C的角度,并不知道该函数的实现是用C还是汇编。更深的原因是因为C的函数名起到表明函数代码起始地址的左右,这个和汇编的label是一致的。
/* cfile.c
* in C,call an asm function, asm_strcpy
* Sep 9, 2004
*/
#include
extern void asm_strcpy(const char *src, char *dest);

int main()
{
const char *s = "seasons in the sun";
char d[32];
asm_strcpy(s, d);
printf("source: %s", s);
printf(" destination: %s",d);
return 0;
}

;asm function implementation
AREA asmfile, CODE, READONLY
EXPORT asm_strcpy

asm_strcpy
loop
ldrb r4, [r0], #1 ;address increment after read
cmp r4, #0
beq over
strb r4, [r1], #1
b loop
over
mov pc, lr
END
在这里,C和汇编之间的参数传递是通过ATPCS(ARM Thumb Procedure Call Standard)的规定来进行的。简单的说就是如果函数有不多于四个参数,对应的用R0-R3来进行传递,多于4个时借助栈,函数的返回值通过R0来返回。
4. 在汇编中调用C的函数
在汇编中调用C的函数,需要在汇编中IMPORT 对应的C函数名,然后将C的代码放在一个独立的C文件中进行编译,剩下的工作由连接器来处理。
;the details of parameters transfer comes from ATPCS
;if there are more than 4 args, stack will be used

EXPORT asmfile
AREA asmfile, CODE, READONLY
IMPORT cFun

ENTRY
mov r0, #11
mov r1, #22
mov r2, #33
BL cFun
END

/*C file, called by asmfile */

int cFun(int a, int b, int c)
{
return a + b + c;
}
在汇编中调用C的函数,参数的传递也是通过ATPCS来实现的。需要指出的是当函数的参数个数大于4时,要借助stack,具体见ATPCS规范。

小结
以上通过几个简单的例子演示了嵌入式开发中常用的C和汇编混合编程的一些方法和基本的思路,其实最核心的问题就是如何在C和汇编之间传值,剩下的问题就是各自用自己的方式来进行处理。以上只是抛砖引玉,更详细和复杂的使用方法要结合实际应用并参考相关的资料。

说明
以上代码在ADS 1.2的工程中编译,并在对应的AXD中软件仿真通过。

 

关键字:ARM  混合编程 引用地址:ARM中C和汇编混合编程及示例

上一篇:基于ARM Cortex-M3的多路数据采集系统的设计
下一篇:ARM设计的高速数据采集远程监控系统技术

推荐阅读最新更新时间:2024-03-16 12:36

ARM人工智能生态联盟宣告成立
  由  ARM  与多家生态系统合作伙伴发起的 ARM 人工智能 生态联盟(AIEC)在上海市徐汇区宣告成立。据悉,联盟旨在联合产业链上下游合作伙伴,围绕以具体应用场景部署为目标,建立以数据、算法、芯片为支撑的互动创新生态体系,拉通云端和终端,加速 人工智能 产业化。此外,兆易创新作为联盟发起企业和理事单位,将围绕推进应用场景部署目标,以GD32智能创新平台和新型存储优势,与上下游合作伙伴展开多层次的合作提升 人工智能 价值化。下面就随网络通信小编一起来了解一下相关内容吧。   目前,首批 ARM 人工智能生态联盟发起企业包括: ARM,Aupera,地平线机器人,海尔集团,寒武纪智能,晶晨半导体,酷芯微电子,Perceptl
[网络通信]
ARM与厚朴投资就罢免吴雄昂一事发布联合声明
2020年6月10日,ARM公司与厚朴投资联合发表声明中称,已经达成罢免ARM中国吴雄昂董事长兼首席执行官的决定。 原文如下: 作为安谋科技(中国)有限公司(简称:安谋中国)的大股东,ARM公司与厚朴投资最近共同在安谋中国董事会决定,罢免吴雄昂先生董事长兼首席执行官的决定符合安谋中国的最大利益。该决议于2020年6月4日举行的安谋中国董事会上达成,全程由位于中国上海的中伦律师事务所的指导下进行。 基于举报人以及数位在职、离职员工的投诉,经过调查发现,美国公民吴雄昂的行为危害到了安谋中国的发展、公司股东以及利益相关者的利益。从多个渠道获得的证据表明,吴雄昂未对公司披露他已经构成的利益冲突,以及违反公司准则的行为。董事会认
[半导体设计/制造]
ARM推出高效、丰富的系统层级多媒体解决方案
ARM今日宣布推出全新集成ARM Mali™多媒体IP套件,能够高效地提供丰富的视觉内容,为现今市场最大量、高达十亿出货量的智能手机与平板电脑市场提供理想的解决方案。 最新的ARM Mali多媒体IP组合代表了ARM在分布式处理领域的扩展,确保以图形为主的内容与视频内容的任务处理能在最合适的处理器上运行,从而在保持最低功耗的前提下,平衡并实现最佳的用户体验。这套新的IP套件包括Mali-V550视频加速器、Mali-DP550显示处理器以及Mali-T800图形处理器(GPU)系列,它们具备高度可配置、可扩展的特性,使得ARM的合作伙伴能够开发多样的多媒体系统级芯片(SoC)。 针对效率进行集成与优化 ARM以系统层级的方式
[嵌入式]
ARM中异常中断问题分析总结
一、ARM中异常中断的类型: 异常中断名称含义复位(Reset) 当处理器复位引脚有效时,系统产生复位异常中断,程序跳转到复位异常中断处理程序处执行。复位异常中断通常用在下面几种情况: 1、系统加电时 2、系统复位时 3、跳转到复位中断向量处执行,称为软复位 未定义的指令当ARM处理器或者是系统中协处理器认为当前指令未定义时,产生未定义指令异常中断。可以通过该异常中断机制仿真浮点向量运算。 软件中断 (softwareinterruptSWI) 这是一个由用户定义的中断指令。可以用于用户模式下程序调用特权操作指令。在实时操作系统(RTOS)中可以通过该机制实现系统功能调用 指令预取中止
[单片机]
ARM发布Cortex-A35,v8-A架构全面进军移动和嵌入式
Cortex-A35成为基于ARMv8-A架构的全新超高功效处理器系列的首款产品 ARM今天宣布推出ARM Cortex -A35处理器,为64位处理器树立功耗效率新标竿。该处理器是基于ARMv8-A处理器架构的全新超高功效CPU系列的首款产品,该系列专为成长快速的移动和嵌入式应用而设计。ARMv8-A架构具有64位和32位运算能力以及完整的加密功能,Cortex-A35因而得以开创更丰富的用户体验。ARM预期Cortex-A35合作伙伴将于2016年底前量产出货。 ARM处理器事业部总经理James McNiven表示: Cortex-A35很自然地承袭了以功耗效率和体积小巧著称的Cortex-A7,迄今已
[嵌入式]
基于ARM9的Linux代码移植
简介:介绍了嵌入式Linux移植的方法和过程,给出了嵌入式开发环境下基于硬件平台ARM9的bootloader、Linux内核移植的实现方案,该方案可为嵌入式系统的应用研究提供操作系统层面的支持。 摘要:介绍了嵌入式Linux移植的方法和过程,给出了嵌入式开发环境下基于硬件平台ARM9的bootloader、Linux内核移植的实现方案,该方案可为嵌入式系统的应用研究提供操作系统层面的支持。 O 引言 随着计算机技术、通信技术以及Internet的飞速发展。嵌入式系统已得到越来越广泛的应用。与此同时,嵌入式系统的复杂性也在不断增加,嵌入式操作系统已经成为其中最重要的组成部分。目前,市场上存在着众多的嵌入式操作系统,而在
[单片机]
基于<font color='red'>ARM</font>9的Linux代码移植
手机GPU性能大幅提升,ARM A77功不可没
不知不觉间已经1月份了,不知道大家有没有过个好年呢?今年对于手机行业来说,中端SoC可以说性能是显著提升,这其中还是因为大多数今年的SoC用上了最新的ARM的A77架构,特别是GPU方面,今年中端处理器在GPU性能上已经比上一代提升明显。 可能很多人都不知道ARM这家公司,也有人觉得眼熟,没错,它在上一年曾经因为某些不可描述的原因上过我们的新闻,但是可以说目前市面上你用到的移动端SoC基本都需要其授权,今天我们就来扒一扒A77架构到底强在哪里。 认识ARM 对于ARM,它就是芯片界的搬运工:“我们(ARM)不生产芯片,我们只提供一个芯片设计的Idea”,听起来是不是很耳熟?想不想某个矿泉水的品牌广告呢?而ARM
[嵌入式]
手机GPU性能大幅提升,<font color='red'>ARM</font> A77功不可没
Arm 宣布推出全新汽车技术,可缩短多达两年的人工智能汽车开发周期
新闻 重 点 : 支持功能安全的全新 Arm 汽车增强 (AE) 处理器将为 AI 驱动的用例带来先进的 Armv9 架构技术和服务器级性能 Arm 针对汽车应用的未来计算子系统将进一步缩短高性能汽车系统的开发时间、降低成本,并带来最大的灵活性 Arm 生态系统首次实现在物理芯片就绪前就可基于虚拟原型解决方案启动软件开发,由此可缩短多达两年的开发周期 Arm 控股有限公司(纳斯达克股票代码:ARM,以下简称“Arm”)今日携手生态系统合作伙伴推出最新的 Arm 汽车增强 (AE) 处理器和虚拟平台,让汽车行业在开发伊始便可应用,助力缩短多达两年的开发周期。 Arm 高级副总裁兼汽车事业部总经理 Dipti Vac
[汽车电子]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved