c语言调用汇编语言
在main.c中调用在test.s中定义的init_1函数,并通过调试的方式跟踪寄存器的内容来验证。
值得注意的是,在ARM中,寄存器R0~R3保存的是函数的参数,当参数大于4个后,多余的参数将会被压入栈中。而返回结果会被保存在R0当中。
main.c代码
#include<stdio.h>
extern void Init_1(void);
int main()
{
Init_1();
return 0;
}
test.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_END
NOP
END ; 必须空格后再写END,不然会被认为是段名,表示程序结束
在keil中设置对应断点。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/b1d21c8335d441998e2d722811b7724b.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YaJ5oSP5Li25Y2D5bGC5qKm,size_20,color_FFFFFF,t_70,g_se,x_16) ![在这里插入图片描述](https://img-blog.csdnimg.cn/51319c44af8e4dc69becd762fd6f069b.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YaJ5oSP5Li25Y2D5bGC5qKm,size_20,color_FFFFFF,t_70,g_se,x_16)
点击build后开始调试 按F11,可以看到R1、R2的值不断增加。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/94eae0ad9dab4d689331ba1db73f2701.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YaJ5oSP5Li25Y2D5bGC5qKm,size_20,color_FFFFFF,t_70,g_se,x_16) 直到值变为0xA,也就是十进制的11的时候退出循环。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/5e5cfd114644487db58795a8198c1031.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YaJ5oSP5Li25Y2D5bGC5qKm,size_20,color_FFFFFF,t_70,g_se,x_16)
修改init_1函数功能再次调用
把init_1函数修改为传入一个整数x,然后返回x+100的值。 main.c代码
# include<stdio.h>
extern int Init_1(int x);
int main(){
int x=Init_1(1);
printf("%d",x);
return 0;
}
test.s代码
AREA My_Function,CODE,READONLY
EXPORT Init_1 ; 与在c文件中定义的Init_1函数关联起来
; 高级语言中的声明和使用变量其实是对板子寄存器的使用,所以我们只需要直接使用寄存器即可
Init_1
ADD R0,#1 ; 将传入的值+1
MOV PC,LR ; LR(R14)保存返回地址,PC(R15)是当前地址,把LR给PC就是从子程序返回,返回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,不然会被认为是段名,表示程序结束
设置断点 ![在这里插入图片描述](https://img-blog.csdnimg.cn/8671121ac71d467383fde7cfc023178a.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YaJ5oSP5Li25Y2D5bGC5qKm,size_20,color_FFFFFF,t_70,g_se,x_16) 重新build后开始调试 进入init_1函数前R0寄存器的值 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2ab92bfc75934dbca5fd916f8277f862.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YaJ5oSP5Li25Y2D5bGC5qKm,size_20,color_FFFFFF,t_70,g_se,x_16)
执行一次后R0的值变为0x65,也就是十进制的101。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/bc18c7bb43ac425e9e33e3424345ec08.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YaJ5oSP5Li25Y2D5bGC5qKm,size_20,color_FFFFFF,t_70,g_se,x_16) 继续调试,到调用printf函数,可以看到x的值为0x65,也就是十进制的101。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/6d1b66ce0b2f4f20a69ae0d69c0e19ba.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YaJ5oSP5Li25Y2D5bGC5qKm,size_20,color_FFFFFF,t_70,g_se,x_16)
在汇编函数中调用c语言函数
在mian.c中定义一个fun函数,作用是把传入的一个整形参数+1再返回。 main.c代码
# include<stdio.h>
extern int Init_1(int x);
int fun(int x);
int main(){
int x=Init_1(1);
printf("%d",x);
return 0;
}
int fun(int x){
return x+2;
}
test.s代码
AREA My_Function,CODE,READONLY
EXPORT Init_1 ; 与在c文件中定义的Init_1函数关联起来
IMPORT fun ; 声明get5 为外部引用
; 高级语言中的声明和使用变量其实是对板子寄存器的使用,所以我们只需要直接使用寄存器即可
Init_1
ADD R0,#1 ;将传入的值+1
MOV R1,#0 ; 设R1寄存器为i
MOV R2,#0 ; 设R2寄存器为j
BL fun ; 调用fun,返回的值传入R0
MOV PC,LR ;LR(R14)保存返回地址,PC(R15)是当前地址,把LR给PC就是从子程序返回,返回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,不然会被认为是段名,表示程序
重新设置断点 ![在这里插入图片描述](https://img-blog.csdnimg.cn/7821686c01d74aa294b6ce7c60ea23b6.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YaJ5oSP5Li25Y2D5bGC5qKm,size_20,color_FFFFFF,t_70,g_se,x_16)
重新build再调试 R0初始值为1。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/0c3552cfbe2a4d209ee28d8744034867.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YaJ5oSP5Li25Y2D5bGC5qKm,size_20,color_FFFFFF,t_70,g_se,x_16) 执行init_1函数后+1 ![在这里插入图片描述](https://img-blog.csdnimg.cn/3d371b4e79294d8390a3c474c15b81e3.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YaJ5oSP5Li25Y2D5bGC5qKm,size_20,color_FFFFFF,t_70,g_se,x_16)
执行完fun函数后再+2 ![在这里插入图片描述](https://img-blog.csdnimg.cn/099f67f1fa704b038ce2ddc9b4d92490.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6YaJ5oSP5Li25Y2D5bGC5qKm,size_20,color_FFFFFF,t_70,g_se,x_16)
|