在嵌入式体系开发中,现在运用的首要编程言语是C和汇编,C++已经有相应的编译器,可是现在运用仍是比较少的。在稍大规划的嵌入式软件中,例如含有OS,大部分的代码都是用C编写的,首要是因为C言语的结构比较好,便于人的了解,而且有许多的支撑库。
__asm
{
instruction [; instruction]
…
[instruction]
}
asm(“instruction [; instruction]”);
#include
void my_strcpy(const char *src, char *dest)
{
char ch;
__asm
{
loop:
ldrb ch, [src], #1
strb ch, [dest], #1
cmp ch, #0
bne loop
}
}
int main()
{
char *a = “forget it and move on!”;
char b[64];
my_strcpy(a, b);
printf(“original: %s”, a);
printf(“copyed: %s”, b);
return 0;
}
在这儿C和汇编之间的值传递是用C的指针来完成的,因为指针对应的是地址,所以汇编中也可以拜访。
#include
int gVar_1 = 12;
extern asmDouble(void);
int main()
{
printf(“original value of gVar_1 is: %d”, gVar_1);
asmDouble();
printf(” modified value of gVar_1 is: %d”, gVar_1);
return 0;
}
;called by main(in C),to double an integer, a global var defined in C is used.
AREA asmfile, CODE, READONLY
EXPORT asmDouble
IMPORT gVar_1
asmDouble
ldr r0, =gVar_1
ldr r1, [r0]
mov r2, #2
mul r3, r1, r2
str r3, [r0]
mov pc, lr
END
#include
extern void asm_strcpy(const char *src, char *dest);
int main()
{
const char *s = “seasons in the sun”;
char d[32];
asm_strcpy(s, d);
printf(“source: %s”, s);
printf(” destination: %s”,d);
return 0;
}
;asm function implementation
AREA asmfile, CODE, READONLY
EXPORT asm_strcpy
asm_strcpy
loop
ldrb r4, [r0], #1 ;address increment after read
cmp r4, #0
beq over
strb r4, [r1], #1
b loop
over
mov pc, lr
END
在这儿,C和汇编之间的参数传递是经过ATPCS(ARM Thumb Procedure Call Standard)的规则来进行的。简略的说便是假如函数有不多于四个参数,对应的用R0-R3来进行传递,多于4个时凭借栈,函数的回来值经过R0来回来。
;the details of parameters transfer comes from ATPCS
;if there are more than 4 args, stack will be used
EXPORT asmfile
AREA asmfile, CODE, READONLY
IMPORT cFun
ENTRY
mov r0, #11
mov r1, #22
mov r2, #33
BL cFun
END
int cFun(int a, int b, int c)
{
return a + b + c;
}
在汇编中调用C的函数,参数的传递也是经过ATPCS来完成的。需求指出的是当函数的参数个数大于4时,要凭借stack,详细见ATPCS标准。
以上经过几个简略的比如演示了嵌入式开发中常用的C和汇编混合编程的一些办法和根本的思路,其实最中心的问题便是如安在C和汇编之间传值,剩余的问题便是各自用自己的方法来进行处理。以上仅仅抛砖引玉,更详细和杂乱的运用办法要结合实际运用并参阅相关的材料。
阐明
以上代码在ADS 1.2的工程中编译,并在对应的AXD中软件仿真经过。
在C和汇编混合编程的时分,存在C言语和汇编言语的变量以及函数的接口问题。
在C程序中界说的变量,编译为.asm文件后,都被放进了.bss区,而且变量名的前面都带了一个下划线。在C程序中界说的函数,编译后在函数名前也带了一个下划线。例如:
extern int num就会变成 .bss _num, 1
extern float nums[5]就会变成.bss _nums, 5
extern void func ( )就会变成 _func,
一
(1) 汇编程序中拜访c程序中的变量和函数。
在汇编程序中,用_XX就可以拜访C中的变量XX了。拜访数组时,可以用_XX+偏移量来拜访,如_XX+3拜访了数组中的XX[3]。
(2) c程序中拜访汇编程序中的变量
假如需求在c程序中拜访汇编程序中的变量,则汇编程序中的变量名有必要以下划线为首字符,并用global使之成为全局变量。
假如需求在c程序中调用汇编程序中的进程,则进程名有必要以下划线为首字符,而且,要根据c程序编译时运用的形式是stack-based model仍是register argument model来正确地编写该进程,使之能正确地获得调用参数。
(3) 在线汇编
在 C程序中直接刺进 asm(“
二 汇编和C接口中寻址方法的改动:
需求留意的是,在C言语中,关于局部变量的树立和拜访,是经过仓库完成的,它的寻址是经过仓库寄存器SP完成的。而在汇编言语中,为了使程序代码变得更为精简,TI在直接寻址方法中,地址的低7位直接包括在指令中,这低7位所能寻址的详细位置可由DP寄存器或SP寄存器决议。详细完成可经过设置ST1寄存器的CPL位完成,CPL=0,DP寻址,CPL=1,SP寻址。在DP寻址的时分,由DP供给高9位地址,与低7位组成16位地址;在SP寻址的时分,16位地址是由SP(16位)与低7位直接相加得来。
因为在C言语的环境下,局部变量的寻址有必要经过SP寄存器完成,在混合编程的时分,为了使汇编言语不影响仓库寄存器SP,一般的方法是在汇编环境中运用DP方法寻址,这样可以使二者互不搅扰。编程中只需留意对CPL位正确设置即可。