如果您无法下载资料,请参考说明:
1、部分资料下载需要金币,请确保您的账户上有足够的金币
2、已购买过的文档,再次下载不重复扣费
3、资料包下载后请先用软件解压,在使用对应软件打开
基于ARM的C语言与汇编语言混合编程C语言与汇编语言混合编程应遵守的规则ATPCS规则2)堆栈的使用规则ATPCS规定堆栈采用满递减类型(FD,FullDescending),即堆栈通过减小存储器地址而向下增长,堆栈指针指向内含有效数据项的最低地址。3)参数的传递规则整数参数的前4个使用r0~r3传递,其他参数使用堆栈传递;浮点参数使用编号最小且能够满足需要的一组连续的FP寄存器传递参数。子程序的返回结果为一个32位整数时,通过r0返回;返回结果为一个64位整数时,通过r0和r1返回;依此类推。结果为浮点数时,通过浮点运算部件的寄存器F0、D0或者S0返回。ATPCS规则例如在一个C源文件中定义了如下求和函数:intadd(intx,inty){return(x+y);}调用add()函数的汇编程序结构如下:IMPORTadd;声明要调用的C函数……MOVr0,1MOVr1,2BLadd;调用C函数add……当进行函数调用时,使用r0和r1实现参数传递,返回结果由r0带回。函数调用结束后,r0的值变成3。3、C程序调用汇编程序的方法C程序调用汇编程序时,汇编程序的书写也要遵循ATPCS规则,以保证程序调用时参数正确传递。在C程序中调用汇编子程序的方法为:首先在汇编程序中使用EXPORT伪指令声明被调用的子程序,表示该子程序将在其他文件中被调用;然后在C程序中使用extern关键字声明要调用的汇编子程序为外部函数。例如在一个汇编源文件中定义了如下求和函数:EXPORTadd;声明add子程序将被外部函数调用……add;求和子程序addADDr0,r0,r1MOVpc,lr……在一个C程序的main()函数中对add汇编子程序进行了调用:externintadd(intx,inty);//声明add为外部函数voidmain(){inta=1,b=2,c;c=add(a,b);//调用add子程序……}当main()函数调用add汇编子程序时,变量a、b的值会给了r0和r1,返回结果由r0带回,并赋值给变量c。函数调用结束后,变量c的值变成3。内嵌汇编在C和C++语言中嵌入汇编语言可以实现一些高级语言中没有的功能。语法__asm__(“instruction...instruction”);//Linuxgcc中支持__asm{instruction…instruction};//ADS中支持asm(“instruction[;instruction]”);//ARMC++中使用ARM内嵌汇编语法asm(汇编语句模板:输出部分:输入部分:修改部分)共四个部分:汇编语句模板,输出部分,输入部分,破坏描述部分,各部分使用“:”格开,汇编语句模板必不可少,其他三部分可选,如果使用了后面的部分,而前面部分为空,也需要用“:”格开,相应部分内容为空。例如:__asm____volatile__("CLI"::"memory")汇编语句模板汇编语句模板由汇编语句序列组成,语句之间使用“;”、“\n”或“\n\t”分开。指令中的操作数可以使用占位符引用C语言变量,操作数占位符最多10个,名称如下:%0,%1…,%9asm(code:outputoperandlist:inputoperandlist:clobberlist);Youcanaddthevolatileattributetotheasmstatementtoinstructthecompilernottooptimizeyourassemblercode.asmvolatile("mov%0,%1,ror#1":"=r"(result):"r"(value));限制字符几个简单的例子Example1:{uint32_t__hi;uint32_t__lo;uint32_t__result;asm("smull%0,%1,%3,%4\n\t""movs%0,%0,lsr%5\n\t""adc%2,%0,%1,lsl%6":"=&r"(__lo),"=&r"(__hi),"=r"(__result):"%r"(x),"r"(y),"M"(SCALEBITS),"M"(32-(SCALEBITS)):"cc");}Example2:一个完整的例子,在gcc上编译通过5、基于ARM的C语言与汇编语言混合编程举例下面是使用C语言编写的主函数:#include"..\inc\config.h"//将有关硬件定义的头文件包含进来unsignedchardata;//定义全局变量voidmain(void){Target_Init();//对目标板的硬件初始化Delay(10