文章目录
一、c语言中调用汇编程序
1. 无参调用
c语言程序main.c
#include<stdio.h>
extern void Init_1(void);
int main()
{
Init_1();
return 0;
}
汇编程序Func.s
AREA My_Function,CODE,READONLY ;这一行必有的除了My_Function可以自己取名以外,其他都是模板
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段
LOOP_END
NOP
END ;必须空格后再写END,不然会被认为是段名,表示程序结束
我们在keil中进行仿真调试,具体如何在keil中创建工程以及如何软件仿真可以参考我以前的文章
断点调试
若我们在MOV R1,#0处设置断点,会发现左上角R1、R2的值都没变,为0
重新设置断点后,每RUN一次,R1、R2都会+1,直至为10跳出循环
2. 有参调用
我们将上面的Func.s修改一下,使原汇编语言 Init_1函数的类型改为 int Init_1(init) ,此函数功能修改为 传入一个整型数x,函数运行后返回整型数 x+100。
修改后的Func.s
AREA My_Function,CODE,READONLY
EXPORT Init_1
Init_1
ADD R6,#100
MOV PC,LR
END
main.c
#include<stdio.h>
extern int Init_1(int);
int main()
{
Init_1(3);
return 0;
}
编译并调试后,能够看到R6的值发生了改变
二、汇编中调用c语言
我们仍然在前面代码的基础做修改,下面是修改后的代码
main.c
#include<stdio.h>
extern int Init_1(int x);
int re(void);
int main()
{
int x = Init_1(420);
printf("%d",x);
return 0;
}
int re(void)
{
return 5;
}
Func.s
AREA My_Function,CODE,READONLY ;这一行必有的 除了My_Function可以自己取名以外,其他都是模板
EXPORT Init_1 ;与在C文件中定义的Init_1函数关联起来
IMPORT re ;声明return1为外部引用
;高级语言中的声明和使用变量其实是对寄存器的使用,所以我们只需要直接使用寄存器即可
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段
LOOP_END
NOP
END ;必须空格后再写END,不然会被认为是段名,表示程序结束
编译调试
可以看到R0变成了5,c函数调用成功
三、总结
在汇编程序中调用c语言其实还可以使用BL+函数名称;汇编函数传入参数需要选择对应的寄存器,因为传递的参数数量有限,不同参数类型对应的寄存器也不同。