ARM编程中使用的C语言是标准C语言,ARM的开发环境实际上就是嵌入了一个C语言的集成开发环境,只不过这个开发环境与ARM的硬件紧密相关。 在使用C语言时,要用到和汇编语言的混合编程。若汇编代码较为简洁,则可使用直接内嵌汇编的方法;否则要将汇编程序以文件的形式加入到项目中,按照ATPCS(ARM/Thumb过程调用标准,ARM/Thumb Procedure Call Standard)的规定与C程序相互调用与访问。 在C程序和ARM汇编程序之间相互调用时必须遵守ATPCS规则。ATPCS规定了一些子程序间调用的基本规则,哪寄存器的使用规则,堆栈的使用规则和参数的传递规则等。
1)寄存器的使用规则 子程序之间通过寄存器r0~r3来传递参数,当参数个数多于4个时,使用堆栈来传递参数。此时r0~r3可记作A1~A4。 在子程序中,使用寄存器r4~r11保存局部变量。因此当进行子程序调用时要注意对这些寄存器的保存和恢复。此时r4~r11可记作V1~V8。 寄存器r12用于保存堆栈指针SP,当子程序返回时使用该寄存器出栈,记作IP。 寄存器r13用作堆栈指针,记作SP。寄存器r14称为链接寄存器,记作LR。该寄存器用于保存子程序的返回地址。 寄存器r15称为程序计数器,记作PC。
2)堆栈的使用规则 ATPCS规定堆栈采用满递减类型(FD,Full Descending),即堆栈通过减小存储器地址而向下增长,堆栈指针指向内含有效数据项的最低地址。
3)参数的传递规则 整数参数的前4个使用r0~r3传递,其他参数使用堆栈传递;浮点参数使用编号最小且能够满足需要的一组连续的FP寄存器传递参数。 子程序的返回结果为一个32位整数时,通过r0返回;返回结果为一个64位整数时,通过r0和r1返回;依此类推。结果为浮点数时,通过浮点运算部件的寄存器F0、D0或者S0返回。
2、汇编程序调用C程序的方法 汇编程序的书写要遵循ATPCS规则,以保证程序调用时参数正确传递。在汇编程序中调用C程序的方法为:首先在汇编程序中使用IMPORT伪指令事先声明将要调用的C语言函数;然后通过BL指令来调用C函数。 例如在一个C源文件中定义了如下求和函数: int add(int x,int y){ return(x+y); } 调用add()函数的汇编程序结构如下: IMPORT add ;声明要调用的C函数 …… MOV r0,1 MOV r1,2 BL add ;调用C函数add …… 当进行函数调用时,使用r0和r1实现参数传递,返回结果由r0带回。函数调用结束后,r0的值变成3。 3、C程序调用汇编程序的方法 C程序调用汇编程序时,汇编程序的书写也要遵循ATPCS规则,以保证程序调用时参数正确传递。在C程序中调用汇编子程序的方法为:首先在汇编程序中使用EXPORT伪指令声明被调用的子程序,表示该子程序将在其他文件中被调用;然后在C程序中使用extern关键字声明要调用的汇编子程序为外部函数。 例如在一个汇编源文件中定义了如下求和函数: EXPORT add ;声明add子程序将被外部函数调用 …… add ;求和子程序add ADD r0,r0,r1 MOV pc,lr …… 在一个C程序的main()函数中对add汇编子程序进行了调用: extern int add (int x,int y); //声明add为外部函数 void main(){ int a=1,b=2,c; c=add(a,b); //调用add子程序 …… } 当main()函数调用add汇编子程序时,变量a、b的值会给了r0和r1,返回结果由r0带回,并赋值给变量c。函数调用结束后,变量c的值变成3。
4、C程序中内嵌汇编语句 在C语言中内嵌汇编语句可以实现一些高级语言不能实现或者不容易实现的功能。对于时间紧迫的功能也可以通过在C语言中内嵌汇编语句来实现。内嵌的汇编器支持大部分ARM指令和Thumb指令,但是不支持诸如直接修改PC实现跳转的底层功能,也不能直接引用C语言中的变量。 嵌入式汇编语句在形式上独立定义的函数体,其语法格式为: __asm { 指令[;指令] …… [指令] } 其中“__asm”为内嵌汇编语句的关键字,需要特别注意的是前面有两个下划线。指令之间用分号分隔,如果一条指令占据多行,除最后一行外都要使用连字符“\”。
5、基于ARM的C语言与汇编语言混合编程举例 下面给出了一个向串口不断发送0x55的例子: 该工程的启动代码使用汇编语言编写,向串口发送数据使用C语言实现,下面是启动代码的整体框架: …… IMPORT Main AREA Init,CODE,READONLY; ENTRY …… BL Main ;跳转到Main()函数处的C/C++程序 …… END ;标识汇编程序结束 下面是使用C语言编写的主函数: #include "..\inc\config.h" //将有关硬件定义的头文件包含进来 unsigned char data; //定义全局变量 void main(void){ Target_Init(); //对目标板的硬件初始化 Delay(10); //延时 data=0x55; //给全局变量赋值 while(1) { Uart_Printf("%x",data); //向串口送数 Delay(10); } }
关键字:C语言 汇编语言 混合编程
引用地址:
C语言与汇编语言混合编程应遵守的规则
推荐阅读最新更新时间:2024-03-16 14:59
单片机中断c语言使用
根据仪陇单片机TINYC使用手册翻译 中断c语言,关于中断的现场保护,由于英文手册还没有看懂,所以空来没有写出。 低级中断,中断保护程序 中断执行前对一些寄存器进行保护 Void intcall tcc_1(void) @ 0x03:low_int 0 中断服务程序 Void intcall tcc(void) @ int 0 中断向量数,是指MCU有几个中断向量,用标号将每种中断向量分开。 编译器根据中断向量数将中断保护程序和中断服务程序结合起来 全局中断向量IntVecIdx 先申明全局中断下向量IntVecIdx Extern int IntVecIdx;// IntVecIdx将占用地址0x10,用户
[单片机]
单片机c语言XBYTE的使用
大家都知道一般的并行扩展总线---地址总线,数据总线和控制总线一般是相互独立的。但单片机由于受引脚的限制,P0口为低8位地址/数据复用口。其读写时序符合intel8080控制时序。使用外部扩展时,wrrd 等控制引脚不需要特殊配置,只使用指令来区分是否访问外部扩展的存储空间或者外部io设备。当使用 movx等这样的指令时,单片机就会自动产生扩展总线做需要的时序。不需要编程者编程实现。但是,有一个问题就是,使用c语言编程的时候,怎么才能使编译出来的程序含有movx这样的指令那?或者说怎么用c语言书写外部扩展总线的程序那? 使用keil 开发单片机程序时,在absacc.h 这个头文件中,有XBYTE这样一个宏。它的定义是 #de
[单片机]
mips汇编语言程序设计实例
MIPS汇编语言学习 首先是: next_a: bne $v0, ‘a’, next_b #依次判断该字符是否是a,b,c,……,A,B,C,……,1,2,3,……,9,0。若是,则输出对应的串,跳转到main,进行下一次输入与判断,若都不是,则输出‘*’,跳转到main,进行下一次输入与判断。 li $v0, 4 #下同,不再赘述 la $a0, a syscall j main .asciiz 表示输出一个字符串,以“\n“换行符结尾。 .data 定义变量 a: .asciiz “Alpha ”。 等于: String a=“Alpha ”; MIPS汇编程序设计 实验目的 1. 掌握QTSPIM的调试技术 2. 了解MIP
[嵌入式]
0802LCD 4位显示程序 PIC单片机C语言程序
#include xc.h #include pic.h //#include head.h #define uchar unsigned char #define uint unsigned int #pragma config FOSC = XT // Oscillator Selection bits (XT oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT ena
[单片机]
单片机C语言实现的CRC算法
1 引言 循环冗余码CRC检验技术广泛应用于测控及通信领域。CRC计算可以靠专用的硬件来实现,但是对于低成本的微控制器系统,在没有硬件支持下实现CRC检验,关键的问题就是如何通过软件来完成CRC计算,也就是CRC算法的问题。 这里将提供三种算法,它们稍有不同,一种适用于程序空间十分苛刻但CRC计算速度要求不高的微控制器系统,另一种适用于程序空间较大且CRC计算速度要求较高的计算机或微控制器系统,最后一种是适用于程序空间不太大,且CRC计算速度又不可以太慢的微控制器系统。 2 CRC简介 CRC校验的基本思想是利用线性编码理论,在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的监督码(既CRC码)r位,并附在信息后边,
[单片机]
pic单片机汇编语言讲解(下)
看到这篇文章的朋友,想必大家对 pic 单片机均具备一定兴趣,或对 pic 单片机具备一定使用需求。前文中,小编曾对 pic 单片机汇编语言进行过部分讲解。本文中,将对 pic 单片机的清零等指令加以讲解,以帮助大家更好掌握 pic 单片机编程。 一、清零指令 1. 寄存器清零指令 实例:CLRW;寄存器 W 被清零 说明:该条指令很简单,其中 W 为 PIC 单片机的工作寄存器,相当于 MCS-51 系列单片机中的累加器 A,CLR 是英语 Clear 的缩写字母。 2. 看门狗定时器清零指令。 实例:CLRWDT;看门狗定时器清零(若已赋值,同时清预分频器) 说明:WDT 是英语 Watchdog Timer 的缩写字
[单片机]
stm32上的c语言可变参数 实现自己的printf
先说明一下,开发平台win7,工具RVMDK(keil),硬件stm32f103ve,打印到超级终端 前两天开始关注一下一直被搁在一边的printf。。。其实应该有一个月前就有看了一下,调用C语言官方库,实现可变参数printf向串口打印字符串,数字等,呵呵,提高级的~~ 先是在百度上看到一篇有关C语言可变参数的文章,感觉不是很难,两天前尝试了一下(其实弄了很久)昨天终于成功了~~(J-Link一步一步跟踪进去的)没有调用C语言官方库的,完全按照自己的理解写的。呵呵,今天就顺便发表一下博文。 可变参数函数声明格式为:type func(type para1, ...); 省略号就表示后面可以没有参数,一个参数,或者多个参数,而且
[单片机]
51单片机-开发板选择
单片机的学习过程十分重视实践操作,仿真软件不过是纸上谈兵,我们需要有一个看得见摸得着的学习工具,那就是单片机开发板! 1.教程所用的开发板 我们知道,学习C语言首先选择的是用哪一个软件做上机实践,那么本教程也一样,需要选择一块开发板来作为模板教学。经过价格和开发板的硬件资源的稳定性考虑,本教程决定选用:金沙滩工作室 KST—51 手把手教你学单片机开发板! 2.选择原因 首先,宋老师的51单片机开发板的硬件设计用到了很多模电知识,可以帮助我们更加扩展的学习,他配套的教程资料《手把手教你学51单片机》有很多基础知识的讲解,而且资料免费公开。其资料后期的代码很灵活的运用了C语言编程技巧,这些都是值得我们参考借鉴的。 那么本
[单片机]