本文内容:本文主要完成在c语言中调用汇编语言,汇编语言的改写以及调试跟踪寄存器的变化,并尝试在汇编语言中调用c语言。
目录
一、在c语言中调用汇编语言
新建一个工程
选择芯片型号,这里我选的是STM32F103VE
配置如下
建立c文件
代码如下
#include<stdio.h>
extern void Init_1(void);
int main()
{
Init_1();
return 0;
}
建立汇编文件
代码如下
AREA My_Function,CODE,READONLY
EXPORT Init_1
Init_1
MOV R1,#0
MOV R2,#0
LOOP
CMP R1,#10
BHS LOOP_END
ADD R2,#1
ADD R1,#1
B LOOP
LOOP_END
NOP
END
对于此段汇编代码的解释:
EXPORT是将c文件中定义的函数相关连起来;
像Init_1、LOOP、LOOP_END这种顶头写的为程序段名,这是跳转程序的参照;
MOV R1,#0
MOV R2,#0
这两句是将R1,R2寄存器的初值设置为0;
CMP R1,#10
BHS LOOP_END
这两句是将R1的值与10相比较,若R1大于10,就调到LOOP_END;
ADD R2,#1
ADD R1,#1
这两句是R1,R2寄存器加1的意思;
B LOOP
这是再次进入循环的标志;
END程序结束。
编译,没有问题
因为需要用到仿真调试,所以需要改一下设置。
设置中Debug下,勾选Use Simulator,将dialog dll下改为DARMSTM.dll ,将parameter下改为-pSTM32F103C8。
设置调好后,点击debug进入调试
点击单步调试,可以看到R1从1变到9,当为A(10在16进制下为A)时 ,跳出汇编程序
二、汇编语言的改写
将原汇编语言 Init_1函数的类型改为 int Init_1(init) ,此函数功能修改为 传入一个整型数x,函数运行后返回整型数 x+100。
c文件改写
代码如下
#include<stdio.h>
extern int Init_1(int x);
int main()
{
Init_1(5);
return 0;
}
汇编文件改写
代码如下
AREA My_Function,CODE,READONLY
EXPORT Init_1
Init_1
ADD R0,#100
END
之所以让R0加100,是因为在arm编程里,函数调用过程中,子函数的参数值传递按顺序存放在r0,r1,r2,r3里,超过4个参数值传递放栈帧里,所以我们给定的参数值默认是放在R0中的,要想实现x+100,就要对R0寄存器加100。
编译,没有错误
点击debug进入调试
我们可以看到R0的初始值为16进制下的60
点击单步运行调到函数,R0变为5
再次点击进入汇编文件,R0加了100,变为16进制下的105为69
三、在汇编语言中调用c语言
在c文件中写入函数Init_1,将主函数放入汇编文件当中,可以发现,将以前的导入函数EXPORT改为了导入INPORT
c文件的改写
代码如下
#include<stdio.h>
extern int Init_1();
int Init_1()
{
int x=5;
return x+100;
}
汇编文件的改写
代码如下
IMPORT Init_1
AREA MYCODE, CODE
EXPORT __main
__main
BL Init_1
END
编译,没有错误
进入debug调试,按F5跳入主函数的断点处,可以看到寄存器R0变为16进制的105为69
四、总结
本次实验,进行了c文件与汇编文件的相互调用,这让我初步理解了一些汇编语言的含义以及相关寄存器的工作原理及顺序,发现并没有想象中的那么难懂,期待以后进一步的汇编编程。
五、参考文章
arm编程,关于函数调用形参实参在通用寄存器和栈帧里的对应关系。用汇编透视c语法操作_ZHONGkunjia的专栏-CSDN博客