今天一早起来,就想写个有c和a51程序的project,但是编译总是出错,这可把我气坏了,因为我在以前做ucos到51上的移植的时候,这可是必须 的一项技术,无论怎么整都没有进步,早饭都没有吃,现在想想,大可不必这么生气,因为当时是在不需要关心这些细节的情况下做的移植,另外遇到困难了,不应
该生气,应该从头研究一下以前的东东,仔细分析,而不是毫无根据的乱改,好啦,总结一下今天的成绩!
预备知识,在c语言中调用a51的函数,那么必须让写的函数得和c51编译的c函数一致的风格,也就是由c51编译的c文件中的函数的目标代码中 跟函数定义相关的部分是什么样子,我们要写一个让C语言调用的汇编a51函数也得是个什么样,而这可以通过阅读《Cx51 Compiler User's
Guide》--> Advanced programming --> Segment
Naming Conventions-->program objects, 可以了解到如下三种对应关系:
|
c 函数定义 |
program objects |
|
Void func (void) |
?PR?FUNC?FILENAME |
|
Void func1 (char x) |
?PR?_FUNC1?FILENAME |
|
Void func2 (void)
reentrant |
?PR?_?FUNC2?FILENAME |
但是,到现在我们还是没法写一个可以在C程序中调用的a51汇编函数,还需要结合《Cx51 Compiler User's Guide》--> Advanced
programming --> Interfacing C to Assembler,这样,我们就可以写个实际的例子了,在uVision中建立一个工程,在工程中添加2个文件:testc.c和testASM.a51文件的内容分别是:
|
#include extern void cntDelay(void); main() { int b; b = 1000; cntDelay(); }//testc.c |
NAME
TESTASM_A51
?PR?FUNCTION?TESTASM_A51 SEGMENT CODE RSEG
?PR?FUNCTION?TESTASM_A51 public
cntDelay cntDelay: mov
r0,#08h ret end ;testASM.a51 |
说明:1.不管定义什么样的汇编函数,下面2行是必须的:
?PR?FUNCTION?TESTASM_A51 SEGMENT
CODE
RSEG
?PR?FUNCTION?TESTASM_A51
2. public
cntDelay定义了一个没有不带参数的函数
为了能更全面的了解汇编函数的编写,下面在以上的例子中增加带有参数的函数和reentrant函数:
|
; 修改后的testASM.a51 NAME TESTASM_A51
?PR?FUNCTION?TESTASM_A51 SEGMENT CODE RSEG
?PR?FUNCTION?TESTASM_A51 public
cntDelay,_cntDelayWithArg,_?cntDelayReentrant,_?cntDelayReentrantArg cntDelay: mov r0,#08h mov r0,#08h mov r0,#08h mov r0,#08h ret _cntDelayWithArg: mov r0,#80h ret _?cntDelayReentrant: MOV R0,#80H RET _?cntDelayReentrantArg: MOV R0,#80H RET end |
|
//修改后的testc.c #include extern void cntDelay(void); extern void cntDelayWithArg(int a); extern void cntDelayReentrant(void) reentrant; extern void cntDelayReentrantArg(int a) reentrant; main() { int b; b = 1000; cntDelay();
cntDelayWithArg(100);
cntDelayReentrant(); cntDelayReentrantArg(100); } |
从上面的汇编程序中可以看到,下面这2行没有变化:
?PR?FUNCTION?TESTASM_A51 SEGMENT
CODE
RSEG
?PR?FUNCTION?TESTASM_A51
这是因为定义a51函数只需要定义了代码段的属性?PR?,就可以了。
当然上面的这些,只是说明了c语言和汇编混合编程的一部分,还有如下的问题需要解决和理解:
1.
函数参数传递是如何实现的?
2.
在C语言中如何实现嵌入式汇编?
这2个问题涉及到《Cx51 Compiler User's
Guide》--> Advanced programming --> Segment
Naming Conventions-->prameters and local variables
和 《Cx51 Compiler User's Guide》-->
Advanced programming --> Interfacing C to Assembler -->Using the SRC
Directive
和 《Cx51 Compiler User's Guide》à compling programs à directives à reference à ASM
3. 汇编程序调用C函数
4. 汇编程序和c程序使用全局变量的问题
等等,以后再写吧!