- 一、c语言调用汇编语言
- 二、修改init_1函数功能再次调用
- 三、在汇编函数中调用c语言函数
- 四、总结
- 五、参考
在main.c中调用在test.s中定义的init_1函数,并通过调试的方式跟踪寄存器的内容来验证。
值得注意的是,在ARM中,寄存器R0~R3保存的是函数的参数,当参数大于4个后,多余的参数将会被压入栈中。而返回结果会被保存在R0当中。
1.main.c代码
#includeextern void Init_1(void); int main() { Init_1(); return 0; }
2.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,不然会被认为是段名,表示程序结束
3.在keil中设置对应断点。
4.点击build后开始调试。按F11,可以看到R1、R2的值不断增加。
5.直到值变为0xA,也就是十进制的11的时候退出循环。
把init_1函数修改为传入一个整数x,然后返回x+100的值。
1.main.c代码
# includeextern int Init_1(int x); int main(){ int x=Init_1(1); printf("%d",x); return 0; }
2.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,不然会被认为是段名,表示程序结束
3.设置断点
4.重新build后开始调试
进入init_1函数前R0寄存器的值
5.执行一次后R0的值变为0x65,也就是十进制的101。
6.继续调试,到调用printf函数,可以看到x的值为0x65,也就是十进制的101。
在mian.c中定义一个fun函数,作用是把传入的一个整形参数+1再返回。
1.main.c代码
# includeextern 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; }
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,不然会被认为是段名,表示程序
3.重新设置断点
4.重新build再调试
R0初始值为1。
5.执行init_1函数后+1
6.执行完fun函数后再+2,最终结果为4
通过这次实验,知道了在ARM中存储参数的寄存器为R0~R3,多余的会储存在栈中,返回结果也是储存在R0中。同时,学会了c语言和汇编语言的混合编程。
五、参考https://blog.csdn.net/weixin_45919652/article/details/120631225



