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

 2024-02-23 04:03:05  阅读 0

参数传递规则。

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

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

[; ]

……

[]

asm(“[;]”);

下面通过一个例子来说明如何在C中嵌入汇编语言。

#

void (const char *src, char *dest)

字符ch;

__asm

环形:

ldrb ch,[源代码],#1

strb ch,[目标],#1

CMP 通道,#0

骨循环

int main()

char *a = "继续前进!";

字符b[64];

(一、二);

(“:%s”,a);

(“:%s”,b);

0;

这里,C和汇编之间的值传递是使用C指针来实现的。 因为指针对应于地址,所以也可以在汇编中访问它们。

2.在汇编中使用C定义的全局变量

内联汇编不需要编辑单独的汇编语言文件,相对简洁,但有很多限制。 当汇编代码较大时,一般放在单独的汇编文件中。 这时,需要在汇编和C之间传递一些数据。最简单的方法就是使用全局变量。

/* cfile.c

* 定义全局变量并作为调用程序

*/

#

整数=12;

(空白);

int main()

(" 的值为:%d", );

();

(" 的值为:%d", );

0;

对应的汇编语言文件

; 通过 main(C 中),到 an ,使用 C 中的 var 。

区号,

ldr r0, =

ldr r1,[r0]

莫夫r2,#2

乘 r3、r1、r2

str r3, [r0]

移动电脑,LR

结尾

3.C语言中调用汇编函数

要在 C 中调用汇编文件中的函数,有两个主要任务要做。 一是在C中声明函数原型并添加关键字; 另一种是在汇编中使用导出的函数名,并使用函数名作为汇编代码。 最后使用 mov pc, lr 返回段的标识符。 然后,就可以在C中使用该函数了。从C的角度来看,不知道该函数是用C实现的还是用汇编实现的。 更深层次的原因是C函数名的作用是指示函数代码的起始地址,与汇编标号一致。

/* cfile.c

* 在C中,调用汇编,

*2004 年 9 月 9 日

*/

#

void (const char *src, char *dest);

int main()

const char *s = "在阳光下";

字符d[32];

(s、d);

(“:%s”,s);

(“:%s”,d);

0;

;汇编

区号,

arm点亮led灯c语言_编写程序点亮led3_c语言代码arm实现点灯的程序段

环形

ldrb r4,[r0],#1; 读后

CMP r4,#0

请求结束

strb r4,[r1],#1

b循环

超过

移动电脑,LR

结尾

这里,C与汇编之间的参数传递是通过ATPCS(ARM Thumb Call)的规定进行的。 简单来说,如果函数的参数不超过4个,则使用R0-R3来传递对应的参数。 如果参数超过4个,则使用堆栈,通过R0返回函数的返回值。

4.在汇编中调用C函数

要在汇编中调用C函数,需要汇编中对应的C函数名称,然后将C代码放在独立的C文件中进行编译,连接器处理剩下的事情。

;来自 ATPCS

;如果参数超过4个,则使用栈

区号,

乐趣

入口

移动 r0,#11

莫夫R1,#22

莫夫R2,#33

BL cFun

结尾

/*C文件,由*/

int cFun(int a, int b, int c)

a+b+c;

在汇编中调用C函数时,参数传递也是通过ATPCS实现的。 需要指出的是,当函数的参数个数大于4时,必须使用栈。 有关详细信息,请参阅 ATPCS 规范。

概括

以上通过几个简单的例子演示了嵌入式开发中常用的C与汇编混合编程的一些方法和基本思想。 其实核心问题是如何在C和汇编之间传递值。 剩下的问题就自己处理吧。 以上只是一个介绍。 更详细、复杂的使用方法应结合实际应用并参考相关资料。

阐明

上述代码在ADS 1.2工程中编译并通过相应AXD中的软件仿真。

标签: 汇编 参数 传递

如本站内容信息有侵犯到您的权益请联系我们删除,谢谢!!


Copyright © 2020 All Rights Reserved 京ICP5741267-1号 统计代码