基于MDK5下的STM32的C语言与汇编语言混合编程

目录

一、在C程序中调用汇编程序

 二、修改汇编语言

三、在汇编程序中调用C程序

 四、寄存器使用规则

六、参考文献


一、在C程序中调用汇编程序

新建一个工程,这里我选择的芯片是STM32F103RC,配置如下:

基于MDK5下的STM32的C语言与汇编语言混合编程

接着创建一个main.c文件

程序代码如下:

#include<stdio.h>
extern void Init_1();
int main(){
	Init_1();
	return 0;
}

 然后再建立一个汇编文件,func.s

程序代码如下:

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

 注:其中EXPORT是将C文件里的相关函数进行调用

       MOV R1,#0 MOV R2,#0 是将寄存器R1和R2赋值为0

       CMP R1,#10 BHS LOOP_END 是将寄存器R1与10进行比较,如果R1>10,就转到LOOP_END

       ADD R2,#1 ADD R1,#1 是将寄存器R2和R1自增1

       B LOOP 是代表再次进入循环

       END 是表示结束程序

由于本次的实验需要用到仿真调试,所以我要点击魔法棒中的Debug,将其中设置为如下图所示:

基于MDK5下的STM32的C语言与汇编语言混合编程

 配置好后,我们点击debug开始调试

点击单步调试Step,观察寄存器R1和R2里面值的变化

我们可以看到寄存器里的R1和R2从0依次递增到了A(即为10),然后跳出循环,结束程序

基于MDK5下的STM32的C语言与汇编语言混合编程

基于MDK5下的STM32的C语言与汇编语言混合编程

 二、修改汇编语言

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

修改main.c为:

# include<stdio.h>

extern int Init_1(int x);

int main(){
	
	int m = Init_1(10);
	printf("%d", m);
	
	return 0;
}

修改func.s为:

    AREA	MY_Function,CODE,READONLY
	EXPORT 	Init_1  

Init_1
	ADD R0,#100   ;将传入的值加100
	MOV PC,LR	;返回R0
	
LOOP	
	CMP R1,#10	  
	BHS LOOP_END  	  
	ADD R2,#1	  
	ADD R1,#1     
	B LOOP		  
	
LOOP_END
	NOP	
	
	
	END  

 编译之后,设置断点开始调试

基于MDK5下的STM32的C语言与汇编语言混合编程

基于MDK5下的STM32的C语言与汇编语言混合编程

此时Init_1(10)的10被传入R0中

基于MDK5下的STM32的C语言与汇编语言混合编程

 这里可以m的值为0x6E(即10进制下的110)说明调用成功了基于MDK5下的STM32的C语言与汇编语言混合编程

三、在汇编程序中调用C程序

接下来在汇编函数中调用一个 C语言写的函数

funs.s

AREA main,CODE,READONLY
	import addf
	ENTRY
	EXPORT __main

__main
	mov r0,#10 ;给两个参数赋值
	mov r1,#12
	bl addf ;调用函数
	end

main.c

#include<stdio.h>
int addf(int a,int b){
	int result=a+b;
	return result;
}

经过仿真调试后,可以看到在这个时候R0和R1已经附上初值10和12

基于MDK5下的STM32的C语言与汇编语言混合编程

 再次点击单步调试,R0里的值就变为之前R0与R1之和,变为16(即十进制下的22)

基于MDK5下的STM32的C语言与汇编语言混合编程

 变量的值我们也可以看见,结果正是我们想要的

基于MDK5下的STM32的C语言与汇编语言混合编程

 

 四、寄存器使用规则

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。它不能用于任何其它用途。

六、参考文献

C语言在ARM中函数调用时,栈是如何变化的? - 云+社区 - 腾讯云为什么会写篇栈变化的文章?做系统分析的话你肯定遇到过一些crash, oops等棘手问题,一般大家都会用 gdb, objdump 或者 addr2line等工...基于MDK5下的STM32的C语言与汇编语言混合编程https://cloud.tencent.com/developer/article/1593645STM32的C与汇编语言混合编程_鹤引的博客-CSDN博客STM32的C与汇编语言混合编程混合编程C语言嵌套汇编调用函数操作无参数有参数汇编语言嵌入C语言总结参考混合编程C语言还是有其局限性。有些硬件地址是没有地址一说的。比如处理器的寄存器,协处理器和协处理器的寄存器,系统控制器等。这些硬件资源是不可能使用C语言指针来访问的,这时就只好应用汇编指令了。汇编程序中调用C语言函数汇编程序使用C语言中定义的全局变量、、C语言中使用汇编程序中定义的全局变量C语言中使用汇编程序中定义的全局变量C语言中内嵌汇编指令C语言嵌套汇编调用函数操作无参数C语基于MDK5下的STM32的C语言与汇编语言混合编程https://blog.csdn.net/weixin_47554309/article/details/120688906?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163387550216780269847606%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=163387550216780269847606&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-5-120688906.pc_search_result_cache&utm_term=STM32%E7%9A%84C%E4%B8%8E%E6%B1%87%E7%BC%96%E8%AF%AD%E8%A8%80%E6%B7%B7%E5%90%88%E7%BC%96%E7%A8%8B&spm=1018.2226.3001.4187

上一篇:使用constexpr时遇到的小坑


下一篇:stm32上阿里云收集一氧化碳