目录
一、C语言调用汇编函数
1、新建工程
2、配置环境
3、建立一个c语言文件
4、建立一个汇编文件
5、测试代码
二、修改参考代码
1、c语言部分改写
2、汇编语言部分改写
3、效果呈现
三、汇编语言调用c语言
1、对c语言的改写
2、对汇编语言的改写
3、运行效果
四、总结
五、参考文献
一、C语言调用汇编函数
1、新建工程
(1)打开软件Keil uVision4
(2)点击菜单栏的Project,然后单击New uVision Project创建一个新的工程。
(3) 在弹出的页面更改你的保存路径,在文件名的位置输入文件名,我在这里输入test1作为文件名。
(4)默认保存类型为Project Files(*.uvproj)
(5)最后单击保存,保存文件。
2、配置环境
(1)选择设备
在弹出的窗口选择STM32F103下拉菜单中的STM32F103C8,点击OK保存
(2)选择运行环境
所需要的软件组件都已经封装完成,直接选择:
- CMSIS中选择CORE;
- Device中选择Startup
- 单击OK保存
3、建立一个c语言文件
鼠标右击左栏的Source Group 1,在弹出的菜单中选择Add New Item to Group
选择文件类型为 C File(.c)
名称保存为 main
输入代码内容如下:
#includeextern void Init_1(void); int main(){ Init_1(); return 0; }
4、建立一个汇编文件
鼠标右击左栏的Source Group 1,在弹出的菜单中选择Add New Item to Group
选择文件类型为 Asm File (.s)
名称保存为 Func
输入如下代码:
AREA My_Function,CODE,READONLY;这一行必有的,除了My_Function可以自己取名以外,其它是模板 EXPORT Init_1 ;与在o文件中定义的Init_1函数关联起来 ;高级语言中的声明和使用变量其实是对板子寄存器的使用,所以我们只需要直接使用寄存器即可 Init_1 MOV R1,#0 ;设R1寄存器 MOV R2,#0 ;设R2寄存器 LOOP ;写在最左边的是程序段的段名,执行跳转程序使用 CMP R1,#10 ;比较R1和10的大小 BHS LOOP_END ;如果R1大于或等于10,则跳转到LOOP_END程序段,反之忽略该语句,直接执行下面的语句 ADD R2,#1 ;j++ ADD R1,#1 ;i++ B LOOP ;执行一次循环后,无条件再次进入循环判断,跳到LOOP段 LOOP_END ;写在最左边的是程序段的段名,执行跳转程序时要用到 NOP END ;必须空格再写END,不然会被认为是段名,表示程序结束
5、测试代码
(1)编译测试
编译成功
(2)仿真器设置
右击左侧菜单栏中的Target 1
选择Options for Target‘Target 1’
在Debug中勾选Use Simulator,进行虚拟调试
将Dialog DLL改为DARMSTM.dll,Parameter更改为 -pSTM32F103C8,用于设置支持STM32103C8的软硬件仿真
选择OK保存
选择菜单栏中的 Start Debug Session 进入调试
单击逐步调试,可以观察到最后R1的值为A,也就是变为10的时候,跳出程序
二、修改参考代码
要求:
修改参考代码,要求将原汇编语言 Init_1函数的类型改为 int Init_1(init) ,此函数功能修改为 传入一个整型数x,函数运行后返回整型数 x+100。 请编程实现,并仿真跟踪调试;
1、c语言部分改写
- 将void修改为int,表示有返回值
- 在 Init_1( )中加入要传递的参数值,此处为2
要求:
修改参考代码,要求将原汇编语言 Init_1函数的类型改为 int Init_1(init) ,此函数功能修改为 传入一个整型数x,函数运行后返回整型数 x+100。 请编程实现,并仿真跟踪调试;
- 将void修改为int,表示有返回值
- 在 Init_1( )中加入要传递的参数值,此处为2
代码如下:
#includeextern int Init_1(int x); int main(){ Init_1(2); return 0; }
2、汇编语言部分改写
代码如下:
AREA My_Function,CODE,READonLY EXPORT Init_1 Init_1 ADD R0,#100 END
这里的原理是:
- 4个以内的参数,直接存放在R0~R3 这4个寄存器里面。
-
4个以后的参数放在堆栈里。
-
如果函数有返回值,那么返回值放在R0里
所以要想实现x+100,对存有返回值的R0寄存器加上100即可
3、效果呈现
在经过编译之后进行仿真
效果如下:
最终的值变为十六进制的66,就是十进制中的102,相较于原来的参数2,增加了100
三、汇编语言调用c语言
1、对c语言的改写
- 将int后的main改为Init_1,作为函数名
- 在.c文件中写入功能段,x+100
#include
extern int Init_1();
int Init_1(){
int x=2;
return x+100;
}
2、对汇编语言的改写
- 加入import段,功能是声明 Init_1为外部引用符号
- 加入BL段,作用是调用c语言函数,返回值在寄存器R0之中
import Init_1
AREA MYCODE, CODE
EXPORT __main
__main
BL Init_1
END
3、运行效果
- 将int后的main改为Init_1,作为函数名
- 在.c文件中写入功能段,x+100
#includeextern int Init_1(); int Init_1(){ int x=2; return x+100; }
2、对汇编语言的改写
- 加入import段,功能是声明 Init_1为外部引用符号
- 加入BL段,作用是调用c语言函数,返回值在寄存器R0之中
import Init_1
AREA MYCODE, CODE
EXPORT __main
__main
BL Init_1
END
3、运行效果
重新编译,并且进行仿真,最后结果如下
R0的值变更为十六进制的66,即十进制的102,完成任务
四、总结
在这次的练习中,我学习了用c语言和汇编语言的相互调用,这让我对于汇编语言以及STM32编程有了进一步的理解。在做实验中遇到了一些困难,但是通过询问同学的方式,克服了这些问题。令我受益匪浅。
五、参考文献
(1条消息) C语言与汇编语言之间的函数调用_Sunlight的博客-CSDN博客_c语言调用汇编https://blog.csdn.net/sinat_27421407/article/details/78829508



