C/C++教程

STM32的C与汇编语言混合编程

本文主要是介绍STM32的C与汇编语言混合编程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

  • 一、C语言调用汇编函数
    • 1.项目创建及源码
    • 2.调试
  • 二、修改函数后再次尝试
    • 1.源码修改
    • 2.调试
  • 三、汇编函数调用C语言函数
    • 1.代码
    • 2.编译

一、C语言调用汇编函数

1.项目创建及源码

在工作区新建如下两个文件:main.c;Func.s
在这里插入图片描述
分别输入以下代码
main.c

# include<stdio.h>

extern void	Init_1(void);

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

Func.s

	AREA	MY_FUNCTION,CODE,READONLY
	EXPORT 	Init_1  ; 与在c文件中定义的Init_1函数关联起来


; 高级语言中的声明和使用变量其实是对板子寄存器的使用,所以我们只需要直接使用寄存器即可

Init_1

	MOV R1,#0     ; 设R1寄存器为i
	MOV R2,#0	  ; 设R2寄存器为j
	
LOOP	; 写在最左边的是程序段的段名,执行跳转程序时用到
	CMP R1,#10	  ; 比较R1和10的大小
	BHS LOOP_END  	  ; 如果R1大于等于10,则跳转到LOOP_END程序段,反之忽略该语句,直接执行下面的语句
	ADD R2,#1	  ; j++
	ADD R1,#1     ; i++
	B LOOP		  ; 循环
	
LOOP_END
	NOP	
	
	END  ; 必须空格后再写END,不然会被认为是段名,表示程序结束

解释 main.c是C语言程序,Func.s是汇编程序,Init在汇编文件里实现,在C文件里调用。

2.调试

上面的代码是将寄存器R1的值与10相比,若小于10,则将R1自增至10。
注意 在C语言中调用汇编函数时,需要在.c文件中用extern 函数返回类型 函数名(); 声明,然后在main函数中调用,在汇编里面用EXPORT 函数名就可以与.c文件中的函数联系起来。
在这里插入图片描述
在这里插入图片描述

二、修改函数后再次尝试

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

1.源码修改

根据要求将源码修改为以下内容
main.c

#include<stdio.h>

extern int Init_1(int x);

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

Func.s

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

2.调试

可以看到R0的值由0变为了101,即16进制的65
在这里插入图片描述

在这里插入图片描述
小结 在这个部分中要明白ARM处理器中参数的传递和使用。
首先来看C语言:

C语言调用函数时,在32位程序中使用栈传递,而在64位程序中,传递方式和参数个数有关,当参数个数小于等于6个时,参数会使用寄存器被传递,当参数大于6个时,6个寄存器被分配后,会利用栈来传递多余的参数,且参数的传递都是从右到左压栈或是存入寄存器。

然后是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 用于其它用途,程序返回时要恢复寄存器 r15 是程序计数器 pc。它不能用于任何其它用途。

三、汇编函数调用C语言函数

1.代码

在c文件和汇编文件内分别输入以下代码
main.c

#include<stdio.h>
extern int sum(int a,int b);
int sum(int a,int b){
  int c;
	a=1;
	b=1;
	c=a+b;
	return c;
}

Func.s

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

__main

    BL sum
	
	BX LR
	
	END

2.编译

编译结果可以看到,R0的值变为2。在这个调用的过程中要注意导入一个C语言函数的格式。
在这里插入图片描述

这篇关于STM32的C与汇编语言混合编程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!