赞
踩
一、实验名称:C语言主程序调用ARM子程序
二、实验目的:
三、实验原理:
由于C语言便于理解,有大量的支持库,所以它是当前ARM程序设计所使用的主要编程语言。
对硬件系统的初始化、CPU状态设定、中断使能、主频设定 以及RAM控制参数初始化等C程序力所不能及的底层操作,还是要由汇编语言程序 来完成。
在应用系统的程序设计中,若所有的编程任务均用汇编语言 来完成,其工作量是可想而知的,这样做也不利于系统升级或应用软件移植。
通常汇编语言部分完成系统硬件的初始化;高级语言部分完成用户的应用。
执行时,首先执行初始化部分,然后再跳转到C/C++部分。整个程序结构显得清晰明了,容易理解。为方便工程开发,ARM公司的开发环境ARM ADS为用户提供了一个可以选用的应用程序框架。该框架把为用户程序做准备工作的程序分成了: 启动代码 和 应用程序初始化 两部分。
用于硬件初始化的汇编语言部分叫做 启动代码;用于应用程序初始化的C部分叫做初始化部分。
2.过程调用标准ATPCS
在ARM工程中,C程序调用汇编函数和汇编程序调用C函数是经常发生的事情。为此人们制定了ARM-Thumb过程调用标准ATPCS(ARM-Thumb Procedure Call Standard)。
3.C/C++语言和汇编语言的混合编程之: 内联汇编和嵌入式汇编
除了上面介绍的函数调用方法之外,ARM 编译器 armcc 中含有的内嵌汇编器还允许在 C 程序中 内联或嵌入式汇编代码,以提高程序的效率。
所谓内联汇编程序,就是在 C 程序中直接编写汇编程序段而形成一个语句块,这个语句块可以使用除了 BX 和 BLX之外的全部ARM指令来编写,从而可以使程序实现一些不能从C获得的底层功能。
其格式为:
__asm
{
汇编语句块
}
内联汇编 与 真实汇编 之间有很大区别,会受到很多限制。
(1)它不支持 Thumb 指令;除了程序状态寄存器 PSR 之外,不能直接访问其他任何物理寄存器等;
(2)如果在内联汇编程序指令中出现了以某个寄存器名称命名的操作数,那么它被叫做虚拟寄存器,而不是实际的物理寄存器。编译器在生成和优化代码的过程中,会给每个虚拟寄存器分配实际的物理寄存器,但这个物理寄存器可能与在指令中指定的不同。唯一的一个例外就是状态寄存器 PSR ,任何对 PSR 的引用总是执行指向物理 PSR;
(3)在内联汇编代码中不能使用寄存器 PC(R15)、LR(R14)和SP(R13),任何试图使用这些寄存器的操作都会导致出现错误消息;
(4)虽然内联汇编代码可以更改处理器模式,但更改处理器模式会禁止使用 C 操作数或对已编译 C 代码的调用,直到将处理器模式恢复为原设置之后。
嵌入式汇编
嵌入式汇编程序是一个编写在C程序外的单独汇编程序,该程序段可以像函数那样被 C 程序调用。
与内联汇编不同,嵌入式汇编具有真实汇编的所有特性,数据交换符合 ATPCS 标准,同时支持 ARM 和Thumb,所以它可以对目标处理器进行不受限制的低级访问。但是不能直接引用 C/C++ 的变量。
用 _ _asm 声明的嵌入式汇编程序,像 C 函数那样,可以有参数和返回值。定义一个嵌入式汇编函数的语法格式为:
__asm return–type function–name(parameter-list)
{
汇编程序段
}
灵活地使用内联汇编和嵌入式汇编,有助于提高程序效率。
三、实验内容:
四、实验器材(设备、元器件):
五、实验步骤:
六、实验结果与分析(含重要数据结果分析或核心代码流程分析)
C语言代码如代码4所示。
代码4 C语言主程序代码
#include<stdio.h> #include<stdlib.h> extern int arm_subfunction(int,int,int,int,int,int); int convertNum(int); int main(){ int x1 = arm_subfunction(1,2,3,4,5,6); int a = 0,b = 1,tmp = 2; __asm{ ADD tmp,a,b MOV R0,#0x08 MUL tmp,R0,tmp } int num = 0xAABBCCDD; num = convertNum(num); } __asm int convertNum(int i){ EOR R1,R0,R0, ROR #16 BIC R1,R1,#0xFF0000 MOV R0,R0,ROR #8 EOR R0,R0,R1,LSR #8 BX LR } |
汇编程序代码如代码5所示。
代码5 C语言主程序调用ARM指令子程序的汇编程序部分
AREA armcode,CODE,READONLY EXPORT arm_subfunction arm_subfunction STMDB SP!,{R4-R5} LDR R4,[SP,#0x08] LDR R5,[SP,#0x0c] ADD R0,R0,R1 ADD R0,R0,R2 ADD R0,R0,R3 MUL R4,R0,R4 SUB R0,R4,R5 LDMIA SP!,{R4-R5} BX LR END |
2、结论分析
(1)C语言调用ARM子程序时,在输入参数多余4个(比如是6个)的情况下前四个参数通过R0-R3传递,后面多余的参数会按照从右向左的顺序压栈。 (2)结果通过R0返回。
(3)ARM通过R0-R3获取前四个参数,后面剩余的参数,通过访问堆栈获取。
3、实验结论
由上述实验结果可知,C语言主程序在调用ARM汇编子程序时,当参数个数多于四个时,前四个参数通过R0-R3传递,多余的参数通过堆栈传递。调用嵌入书汇编程序函数的过程与之类似。C语言程序执行内联汇编代码时,可以直接使用C语言程序中的变量。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。