单片机编程中在C语言里嵌入汇编比较常见,只需要在嵌入前后写入:
#pragma asm
MOV A,#0x00
#pragma endasm
两个声明即可,在它们中间就可以使用汇编代码,
因为汇编是机器码,执行速度快,在对程序运行速度要求高的地方嵌入汇编可以大大提高运行速率,
但是当我们在C函数中需要汇编来调用其他的C函数时,传递参数就会变得复杂,
例:
-
void fix_data()
-
{
-
#pragma asm
-
PUSH ACC
-
loop:
-
MOV R11,@DR12
-
MOVX @DPTR,A
-
INC DPTR
-
INC WR14,#
0x01
-
DJNZ R0,loop
-
POP ACC
-
#pragma endasm
-
}
-
-
U8 Fun(U8 far *xPA,U8 far *yPA,U8 far *M,U8 M_Length,U8 far *Sig_R,U8 far *Sig_S)
-
{
-
//For_Share_Lib_xdata[0] = *M;
-
#pragma asm
-
//保存DR12的值
-
PUSH DR12
-
//填写参数M
-
MOV DPXL,#
0X01
-
MOV DTPR,#
0X0008
-
MOV WR12,#WORD2 M?
140
-
MOV WR14,#WORD0 M?
140
-
MOV R0,#
0X04
-
ECALL fix_data?
-
//填写参数Sig_R,Sig_S
-
MOV DPTR,#
0X000D
-
MOV WR12,#WORD2 Sig_R?
142
-
MOV WR14,#WORD0 Sig_R?
142
-
MOV R0,#
0X08
-
ECALL fix_data?
-
//调用函数
-
ECALL
0xFF0010
//函数地址
-
//恢复DR12的值
-
POP DR12
-
#pragma endasm
-
}
如上例所示,在Fun函数中需要嵌入汇编,使用汇编调用一个固定地址函数,并将所有参数传递过去,本例中使用的是16位单片机寄存器包含R0,R1,R2,R3,R4,R5,R6,R7,R11
Fun函数中每个指针参数需要占用4字节,因此两个指针参数就需要占用8个寄存器,所以*xPA和*yPA可以通过寄存器进行传递,其他的参数则需要通过XRAM进行传递,因此需要先找到被调用函数中对应参数的地址(在Map文件中查找),本例中*M参数的地址为0x010008,*M被编译后的名字变成了M?140,其名字需要去掉
//For_Share_Lib_xdata[0] = *M;
注释后编译,然后在Map文件中找到编译后变量被改成了什么名字,
MOV R0,#0x04 中0x04为传递参数占用的字节数
接着就是调用fix_data()函数,将该变量名对应到XRAM地址上去,如此参数传递完成。
其中M_Length为一个字节可通过R11进行传递。