keil 在 c 中调用 a51汇编函数

2717阅读 0评论2008-04-18 abelard2008
分类:C/C++

今天一早起来,就想写个有ca51程序的project,但是编译总是出错,这可把我气坏了,因为我在以前做ucos51上的移植的时候,这可是必须 的一项技术,无论怎么整都没有进步,早饭都没有吃,现在想想,大可不必这么生气,因为当时是在不需要关心这些细节的情况下做的移植,另外遇到困难了,不应 该生气,应该从头研究一下以前的东东,仔细分析,而不是毫无根据的乱改,好啦,总结一下今天的成绩!


 
预备知识,在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.ctestASM.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程序使用全局变量的问题

等等,以后再写吧!

 

上一篇:没有了
下一篇:数字电子常见问题