[嵌入式]STM32的C和汇编语言混合编程

文章目录

  • 一.Keil下C语言调用汇编程序
  • 二、将原汇编语言 Init\_1函数的类型改为 int Init\_1(init) ,此函数功能修改为 传入一个整型数x,函数运行后返回整型数 x+100。
    • 1.C语言调用函数传递参数的方法
    • 2.ARM中寄存器用法
    • 3.实验过程
  • 三、在汇编函数中调用一个C语言写的函数
  • 四、总结
  • 五、参考链接

一.Keil下C语言调用汇编程序

在项目下新建文件main.c和Func.s

[嵌入式]STM32的C和汇编语言混合编程_第1张图片

main.c

#include

extern void Init_1(void);

int main(){
	
	Init_1();
	
	return 0;
}

Func.s


    AREA My_Function,CODE,READONLY
	EXPORT Init_1
		
		
Init_1
    MOV R1,#666
	MOV R2,#888
	
LOOP
    CMP R1,#10
	BHS LOOP_END
	ADD R2,#1
	ADD R1,#1
	B LOOP
	
LOOP_END
    NOP
	
	END

编译调试:

[嵌入式]STM32的C和汇编语言混合编程_第2张图片

可以看见c语言成功调用汇编程序。

在C语言中调用汇编函数时,需要在.c文件中用extern 函数返回类型 函数名(); 声明,然后在main函数中调用,在汇编里面用EXPORT 函数名就可以与.c文件中的函数联系起来。

二、将原汇编语言 Init_1函数的类型改为 int Init_1(init) ,此函数功能修改为 传入一个整型数x,函数运行后返回整型数 x+100。

在这里我们首先要搞清楚在ARM中参数是如何传递和使用的
在X86平台下:

1.C语言调用函数传递参数的方法

C语言调用函数时,在32位程序中使用栈传递,而在64位程序中,传递方式和参数个数有关,当参数个数小于等于6个时,参数会使用寄存器被传递,当参数大于6个时,6个寄存器被分配后,会利用栈来传递多余的参数,且参数的传递都是从右到左压栈或是存入寄存器。
验证过程参考:https://blog.csdn.net/m0_55708805/article/details/117388229

2.ARM中寄存器用法

  1. r0-r3 用作传入函数参数,传出函数返回值。在子程序调用之间,可以将 r0-r3 用于任何用途。被调用函数在返回之前不必恢复 r0-r3。—如果调用函数需要再次使用 r0-r3 的内容,则它必须保留这些内容。
  2. r4-r11 被用来存放函数的局部变量。如果被调用函数使用了这些寄存器,它在返回之前必须恢复这些寄存器的值。r11 是栈帧指针 fp。
  3. r12 是内部调用暂时寄存器 ip。它在过程链接胶合代码(例如,交互操作胶合代码)中用于此角色。在过程调用之间,可以将它用于任何用途。被调用函数在返回之前不必恢复
    r12。
  4. 寄存器 r13 是栈指针 sp。它不能用于任何其它用途。sp 中存放的值在退出被调用函数时必须与进入时的值相同。
  5. 寄存器 r14 是链接寄存器 lr。如果您保存了返回地址,则可以在调用之间将 r14 用于其它用途,程序返回时要恢复
  6. 寄存器 r15 是程序计数器 pc。它不能用于任何其它用途。

利用寄存器传递参数时,参数值按顺序放在寄存器R0,R1,R2,R3中,当参数大于4个时,超过的参数值利用栈传递,函数返回时,若有返回值会利用寄存器R0存储返回。

3.实验过程

修改main.c文件内容

main.c

#include

extern int Init_1(int x);

int main(){
	
	Init_1(25);
	
	return 0;
}

文件Func.s内容为


    AREA My_Function,CODE,READONLY
	EXPORT Init_1
    ENTRY
		
Init_1
    ADD R0,R0,#100
	
	BX LR
	
	END

编译调试得到结果如下:

[嵌入式]STM32的C和汇编语言混合编程_第3张图片

在该实验中,我们的Init_1函数调用时有一个参数的传递,在main函数中我们调用Init_1函数,给了一个参数25,函数执行完毕时,25+100的16进制数为7D,我们对函数执行完毕的期望值为7D,而在图中寄存器R0的值就是7D,任务完成。

三、在汇编函数中调用一个C语言写的函数

在汇编中调用C语言函数XXX,则加上IMPORT XXX,注意Keil工具不允许汇编语句顶格写,否则会报错。

新建Func.c文件

Func.c

#include
extern int sum(int a,int b);
int sum(int a,int b){
  int c;
	a=100;
	b=100;
	c=a+b;
	return c;
}

新建test1.s文件

test1.s

 AREA MYDATA, DATA
	IMPORT sum
 AREA MYCODE, CODE
	ENTRY
	EXPORT __main

__main

    BL sum
	
	BX LR
	
	END

编译调试结果如下:

[嵌入式]STM32的C和汇编语言混合编程_第4张图片

可以看见C函数被成功调用。

四、总结

通过本实验的学习,对C语言调用函数参数的传递方式以及ARM寄存器使用方法有了更加深刻的理解。

五、参考链接

https://blog.csdn.net/m0_55708805/article/details/117388229
https://blog.csdn.net/ZHONGkunjia/article/details/51184489
http://lionwq.spaces.eepw.com.cn/articles/article/item/17475/
https://cloud.tencent.com/developer/article/1593645

你可能感兴趣的:(学习,stm32,c语言,arm)