C语言直观清晰,汇编效率高,C语言里面嵌套汇编是很好的选择。
- 前言
- 1、创建工程
- 1.1 创建新的项目
- 1.2 Add New Item to Group
- 1.2 编写程序
- 1.3 配置目标
- 2、进行调试(无参数)
- 2.1 设置断点
- 2.2 编译并调试
- 3、 进行调试(有参数)
- 3.1 修改代码
- 3.2 编译并调试
- 4. 汇编函数调用C语言
- 4.1 修改代码
- 4.2 断点设置
- 4.3 编译并调试
- 总结
前言
在STM32汇编语言编程与仿真调试的基础上,继续学习Keil下STM32的C与汇编语言混合编程。
1、创建工程
创建过程与之前文章中的一样,此处简写,详情参考:https://blog.csdn.net/isyuuun/article/details/120559821
1.1 创建新的项目
main.c的程序如下:
#includeextern 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,不然会被认为是段名,表示程序结束1.3 配置目标
在“Debug”选项卡中选择“Use Simulator”,表示使用软件仿真;选择“Run to main()”则表示跳过汇编代码,直接跳转到main函数开始仿真。设置下面的“Dialog DLL”项为“DARMSTM.DLL”;parameter项为“-pSTM32F103C8”,用于设置支持STM32F103C8的软硬件仿真。
光标到达指定行,F9按键即可
运行结果:(部分)
直到R1和R2都变成了0x0000000A(从0加到了10)
将原汇编语言 Init_1函数的类型改为 int Init_1(init) ,此函数功能修改为 传入一个整型数x,函数运行后返回整型数 x+100。
修改后main.c函数:
# includeextern int Init_1(int x); int main(){ int xx = Init_1(10); printf("%d", xx); return 0; }
Func.s程序如下:
AREA MY_Function,CODE,READonLY EXPORT Init_1 ; 与在c文件中定义的Init_1函数关联起来 ; 高级语言中的声明和使用变量其实是对板子寄存器的使用,所以我们只需要直接使用寄存器即可 Init_1 ADD R0,#100 ; 将传入的值+100 MOV PC,LR ; 返回R0 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,不然会被认为是段名,表示程序结束
3.2 编译并调试Init_1(10)传入的10放到了R0,由MOV PC,LR返回110.
- 设置断点
- 调试结果
Func.s
AREA MY_Function,CODE,READonLY EXPORT Init_1 ; 与在c文件中定义的Init_1函数关联起来 import get5 ; 声明get5 为外部引用 ; 高级语言中的声明和使用变量其实是对板子寄存器的使用,所以我们只需要直接使用寄存器即可 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++ BL get5 ; 调用get5,返回的值传入R0 B LOOP ; 循环 LOOP_END NOP END ; 必须空格后再写END,不然会被认为是段名,表示程序结束
main.c
# include4.2 断点设置extern void Init_1(void); int get5(void); int main(){ printf("Begin...n"); Init_1(); return 0; } int get5(){ return 5; }
总结 在调试过程中一定要注意很多细节,call stack+locals窗口显示会给出main的主要信息。
参考文章:https://blog.csdn.net/weixin_46628481/article/details/120651674
https://blog.csdn.net/sinat_27421407/article/details/78829508



