ARM之汇编与C混合编程

发布者:chunxing最新更新时间:2016-11-25 来源: eefocus关键字:ARM  汇编  混合编程 手机看文章 扫描二维码
随时随地手机看文章

     于ARM体系来说,不同语言撰写的函数之间相互调用(mix calls)遵循的是 ATPCS(ARM-Thumb Procedure Call Standard),ATPCS主要是定义了函数呼叫时参数的传递规则以及如何从函数返回,详细内容可以查看ADS1.2 Online Books ——Developer Guide的2.1节。这篇文档要讲的是 汇编代码中对C函数调用时如何进行参数的传递以及如何从C函数正确返回。
       不同于x86的参数传递规则,ATPCS建议函数的形参不超过4个,如果形参个数少于或等于4,则形参由R0,R1,R2,R3四个寄存器进行传递;若形参个数大于4,大于4的部分必须通过堆栈进行传递。

ATPCS中个寄存器使用规则及别名

ARM之汇编与C混合编程 - tianwaike1 - 开拓-进取

说明:

1子程序中通过r0~r3传递参数,被调用的子程序返回前无需恢复r0~r3的内容。

2子程序中使用r4~r11保存局部变量,如果子程序中使用了它们中某些寄存器,子程序进入时要保存这些寄存器的值,在返回时恢复它们。在Thumb程序中,通常只能使用r4~r7来保存局部变量。

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; } 
对应的汇编语言文件 

;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 */ 

PDF created with pdfFactory trial version www.pdffactory.com 
int cFun(int a, int b, int c) 

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

在C和汇编混合编程的时候,存在C语言和汇编语言的变量以及函数的接口问题。
在C程序中定义的变量,编译为.asm文件后,都被放进了.bss区,而且变量名的前面都带了一个下划线。在C程序中定义的函数,编译后在函数名前也带了一个下划线。例如:

extern int num就会变成 .bss _num, 1
extern float nums[5]就会变成.bss _nums, 5
extern void func ( )就会变成 _func,

一    汇编和C的相互调用可以分以下几种情况:

(1) 汇编程序中访问c程序中的变量和函数。
在汇编程序中,用_XX就可以访问C中的变量XX了。访问数组时,可以用_XX+偏移量来访问,如_XX+3访问了数组中的XX[3]。

     在汇编程序调用C函数时,如果没有参数传递,直接用_funcname 就可以了。如果有参数传递, 则函数中最左边的一个参数由寄存器A给出,其他的参数按顺序由堆栈给出。返回值是返回到A寄存器或者由A寄存器给出的地址。同时注意,为了能够让汇编语言 能访问到C语言中定义的变量和函数,他们必须声明为外部变量,即加extern 前缀。

(2) c程序中访问汇编程序中的变量

如果需要在c程序中访问汇编程序中的变量,则汇编程序中的变量名必须以下划线为首字符,并用global使之成为全局变量。

如果需要在c程序中调用汇编程序中的过程,则过程名必须以下划线为首字符,并且,要根据c程序编译时使用的模式是stack-based model还是register argument model来正确地编写该过程,使之能正确地取得调用参数。

(3) 在线汇编

在C程序中直接插入 asm(“   ***   ”),内嵌汇编语句,需要注意的是这种用法要慎用,在线汇编提供了能直接读写硬件的能力,如读写中断控制允许寄存器等,但编译器并不检查和分析在线汇编语 言,插入在线汇编语言改变汇编环境或可能改变C变量的值可能导致严重的错误。

二 汇编和C接口中寻址方式的改变:

需要注意的是,在C语言中,对于局部变量的建立和访问,是通过堆栈实现的,它的寻址是通过堆栈寄存器SP实现的。而在汇编语言中,为了使程序代码变得更为 精简,TI在直接寻址方式中,地址的低7位直接包含在指令中,这低7位所能寻址的具体位置可由DP寄存器或SP寄存器决定。具体实现可通过设置ST1寄存 器的CPL位实现,CPL=0,DP寻址,CPL=1,SP寻址。在DP寻址的时候,由DP提供高9位地址,与低7位组成16位地址;在SP寻址的时 候,16位地址是由SP(16位)与低7位直接相加得来。

由于在C语言的环境下,局部变量的寻址必须通过SP寄存器实现,在混合编程的时候,为了使汇编语言不影响堆栈寄存器SP,通常的方式是在汇编环境中使用DP方式寻址,这样可以使二者互不干扰。编程中只要注意对CPL位正确设置即可

 

中断异常事件:

      ADS编译器中有一个特殊的声明_iaq,这是专门用来处理异常程序而写C语言的声明。有三个用途:

1.进入程序第一件事,将C语言及异常要用到的寄存器存入堆栈中.

2.离开的时候将保存的寄存器取出来

3.改变程序计数器PC的值为lr-4,用于中断返回

例:

irq void IsrIRQ  ()                                  对应的汇编:                           IsrIRQ

{                                                                                                           STMFD   SP!,{R0-R4,R12,LR}

...                                                                                                          ...

}                                                                                                           LDMFD   SP!,{R0-R4,R12,LR}

                                                                                                            SUBS  PC,LR,#4

若去掉关键字 irq,对应的汇编如下:

IsrIRQ

STMFD   SP!,{R4,LR}

...

 LDMFD   SP!,{R4,LR}


关键字:ARM  汇编  混合编程 引用地址:ARM之汇编与C混合编程

上一篇:s3c2410开发板的VGA调试
下一篇:i2c驱动之i2c-s3c2410.c

推荐阅读最新更新时间:2024-03-16 15:22

印度推首款本土ARM芯片:5nm工艺 96核
5月15日消息,对于印度来说,他们正在加大资金支持力度,为的是本土处理器的研发。 现在,印度高级计算发展中心 (C-DAC) 宣布正在本土首款ARM架构的CPU,其整体参数看起来还是相当不错。 从公布的这款AUM处理器看,提供96个ARM内核(ARM Neoverse V1架构,每个小芯片包含 48个V1内核)、96GB HBM3、128 个 PCIe Gen 5通道,基于台积电5nm工艺。 此外,这款处理器的TD是320W,两个芯片上都内置了96MB的二级缓存和96MB的系统缓存,主频3-3.5GHz,其双插槽服务器可以支持最多4个标准GPU加速器,其最快会在年底上市。 C-DAC还准备了Vega系列CPU基于双核和四
[半导体设计/制造]
Ubuntu9.10制作ARM交叉编译器
本环境内核版本:Linux ubuntu910 2.6.31-21-generic #59-Ubuntu SMP i686 GNU/Linux 准备软件包如下: bison_13a2.3.dfsg-4build1_i386.deb build-essential_11.4_i386.deb flex_2.5.33-10build1_i386.deb libncurses5-dev_5.6+20071124-1ubuntu2_i386.deb m4_1.4.8-1build1_i386.deb patch_2.5.9-5_i386.deb gcc-3.4.5.tar.gz glibc-2.3.6.tar.gz l
[单片机]
汇编技术内幕(2)
问题:为什么用EAX寄存器保存函数返回值? 实际上IA32并没有规定用哪个寄存器来保存返回值。但如果反汇编Solaris/Linux的二进制文件,就会发现,都用EAX保存函数返回值。这不是偶然现象,是操作系统的ABI(Application Binary Interface)来决定的。Solaris/Linux操作系统的ABI就是Sytem V ABI。 概念:SFP (Stack Frame Pointer) 栈框架指针 正确理解SFP必须了解: IA32 的栈的概念 CPU 中32位寄存器ESP/EBP的作用 PUSH/POP 指令是如何影响栈的 CALL/RET/LEA
[单片机]
基于STC89C52的智能印章机的设计方案
在银行、政府、学校等机构存在大量文件需要盖章,当需要盖章文件数量过大时则需要消耗大量的人力和时间,本文中设计的智能印章机能明显缩短印章时间并且节约大量人力,满足日常办公所需。并且具有手动设置功能,可通过手动设置盖章的延时时间,和盖章的数量本文设计的智能印章机控制电路的主要组成部分由:供电电路、电机驱动电路、传感器电路、数据存储电路、数据显示电路、手动控制电路组成。 1 系统总体框图 智能印章机盖章的工作原理是通过安装在机器底部的光电传感器检测是否有纸张的信号来开启单片机对电机的控制,通过一系列的传动结构带动印章运动完成盖章动作。盖章动作前可以通过手动控制面板对盖章数量、盖章延时进行调节。同时在印章机工作时,印章机所盖的纸张数会被数
[电源管理]
基于STC89<font color='red'>C</font>52的智能印章机的设计方案
keil C51 部分运算符与表达式
keil C51 部分运算符与表达式 ;2013年12月2日10:39:34 ?: 用于表达式求值运算符;逻辑表达式?表达式1:表达式2。逻辑表达式为真执行表达式1,否者执行表达式2. , 用于把若干个表达式组合成一个表达式;从中到右算出整个表达式的值,最终值就是最右边表达式的值。 * 用于取内容运算符; & 用于取地址运算符; sizeof 用于计算数据类型所占的字节数; -------------------------------------------------------------------------------------------------------------- 1、if (条件表达式1) { 语
[单片机]
采用数字信号处理器TMS320C6201构成的视频跟踪警戒装置
    摘要: 介绍了一种以高速数字信号处理器TMS320C6201为核心器件构成的视频跟踪警戒装置。该视频跟踪警戒装置,即可自成一个小系统,独立进行工作;也可作为一个子系统,装在其它光电测量跟踪系统中工作。     关键词: 电视跟踪 匹配跟踪 图像处理 数字信号处理器     在光电测量跟踪系统的实际应用中,对其视频器量跟踪部分,提出了越来越高的要求。例如,有越来越多的应用场合,要求光电测量跟踪系统对更大区域的视频图像具有实时匹配跟踪(相关跟踪)的功能。在匹配跟踪(相关跟踪)过程中,如果需要匹配处理的图像区域较大,则运算量非常可观。在视频跟踪当中,为了能够在有限的时间(如20毫秒时间内)实现大量的运算处理
[应用]
51单片机汇编语言:位操作指令有哪些?
数据 位传送指令 MOV C, bit ;bit 可直接寻址位 C←(bit) MOV bit,C ;C 进位位 (bit) ← C 位变量修改指令 CLR C ; 将C=0 CLR bit CPL C ; 将C求反再存入C CPL bit ; 将bit求反再存入bit SETB C ; 将C=1 SETB bit ; (bit) ← 1 位变量逻辑指令 ANL C, bit ANL C, bit ORL C, bit ORL C, bit
[单片机]
基于ARM核的ADμC7O26硬件系统开发及其在医疗仪器中的应用
0 引言 随着人们生活水平的不断提高,人们对于自身健康的关注也提升到一个前所未有的高度。在今天,越来越多的高科技手段开始运用到医疗仪器的设计当中。心电图、脑电图等生理参数检测设备,各类型的监护仪器,超声波、X射线成影设备,核磁共振仪器,以及各式各样的物理治疗仪都开始在各地医院广泛使用,并且医学仪器正在向着组合式、多功能、智能化和微型化方向发展。现代的医学仪器一般都广泛采用了嵌入式微处理器来增强仪器的智能化程度,提高其稳定性和数据处理的精确性,使医学信号的采集、处理、通信一体化,并具有自诊断、自校验等一系列优点。其中ARM(Advanced RISC Machines)嵌入式微型主板作为中央处理模块,凭借自身体积小巧、功能强大、
[单片机]
基于<font color='red'>ARM</font>核的ADμ<font color='red'>C</font>7O26硬件系统开发及其在医疗仪器中的应用
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

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