关于C51与汇编的混合编译.docx

上传人:b****4 文档编号:12210263 上传时间:2023-04-17 格式:DOCX 页数:14 大小:22.47KB
下载 相关 举报
关于C51与汇编的混合编译.docx_第1页
第1页 / 共14页
关于C51与汇编的混合编译.docx_第2页
第2页 / 共14页
关于C51与汇编的混合编译.docx_第3页
第3页 / 共14页
关于C51与汇编的混合编译.docx_第4页
第4页 / 共14页
关于C51与汇编的混合编译.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

关于C51与汇编的混合编译.docx

《关于C51与汇编的混合编译.docx》由会员分享,可在线阅读,更多相关《关于C51与汇编的混合编译.docx(14页珍藏版)》请在冰豆网上搜索。

关于C51与汇编的混合编译.docx

关于C51与汇编的混合编译

请教:

关于C51与汇编的混合编译

作者:

leonyang 栏目:

单片机

请教:

关于C51与汇编的混合编译

在下第一次用C51,计划用汇编写底层,用C51写应用层。

  但是不知道C51跟汇编之间的结构应该是怎样的,才能顺利编译。

  汇编的程序是不是跟C51的分别在不同的文件还是同一文件下,两种我都试过,没有成。

一下就是小弟的一段实验代码,请高人指点一二,不胜感激!

#define  uintunsignedint

#include

externvoidgetval(uinti);

voidmain(void)

{

   uintdatai=10;

   uintdataj=0;

   getval(i);

}

   PUBLIC  _getval

   getvalpSEGMENTCODE

   RSEG    getvalp

  _getval:

NOP

           MOVA,R6

           MOVB,R7

           RET

           END

报告有错如下:

errorC129:

missing';'before'_getval'

请英雄们赐教,谢谢了!

2楼:

>>参与讨论

作者:

gaozt于2005-5-317:

16:

00发布:

不能这样简单的混合吧!

看一下keil里的帮助文件!

3楼:

>>参与讨论

作者:

leonyang于2005-5-522:

17:

00发布:

谢谢各位英雄

小弟一直以来都是用汇编的,这是第一次用C51,还请各位英雄指教。

  在下对C51的一些技巧不太了解。

见笑了。

  C51的用户向导看过了。

对寄存器等方面有了解啦,但是还是没有明白

  各个部分之间是怎样的一种结构。

  谢谢收看

4楼:

>>参与讨论

作者:

2shift于2005-5-68:

36:

00发布:

注意:

1:

汇编代码单独做一个asm文件。

2:

asm文件里面getval应大写

5楼:

>>参与讨论

作者:

studyboy_0于2005-5-69:

15:

00发布:

汇编代码单独做一个asm文件,C51怎么去调用呢?

请高手赐教.

 

6楼:

>>参与讨论

作者:

leonyang于2005-5-610:

05:

00发布:

TO:

2SHIFT

谢谢英雄赐教。

但是在下曾经将ASMAND C51文件独立为两个不同的文件,但是同时置于

同一个工程文件目录之下的源码文件夹中。

但是好像编译不了。

不知道这其中还有什么要注意要点?

还望英雄赐教一二。

原来一直用汇编,现在要求用C51,只在是没有办法,只能求教各位大侠了。

7楼:

>>参与讨论

作者:

qjc.j于2005-5-610:

34:

00发布:

其实并不难

曾经有一个主题讨论过,主题名是<这是keilc51混编的>,你看以下吧!

8楼:

>>参与讨论

作者:

2shift于2005-5-613:

54:

00发布:

to:

leonyang

在同一个工程下面能够编译,调用的时候采用extern

注意:

大写,大写+下划线的区别

9楼:

>>参与讨论

作者:

leonyang于2005-5-622:

01:

00发布:

谢谢

谢谢各位英雄的赐教。

小弟感激不禁。

等我试一试先。

有啦结果一定告诉大家。

10楼:

>>参与讨论

作者:

linwei1234于2005-5-721:

57:

00发布:

好象不能放在一个文件里只能调用吧!

 

11楼:

>>参与讨论

作者:

tdsun33于2005-5-89:

12:

00发布:

看看这样行不行

#define  uintunsignedint

#include

externvoidgetval(uinti);

voidmain(void)

{

   uintdatai=10;

   uintdataj=0;

   getval(i);

}  

   NAME  TRANGE

   ?

PR?

_getval?

TRANGESEGMENTCODE

   PUBLIC  _getval

   RSEG    ?

PR?

_getval?

TRANGE

  _getval:

NOP

           MOVA,R6

           MOVB,R7

           RET

           END

12楼:

>>参与讨论

作者:

tdsun33于2005-5-89:

14:

00发布:

看看

最好把

  NAME  TRANGE

   ?

PR?

_getval?

TRANGESEGMENTCODE

   PUBLIC  _getval

   RSEG    ?

PR?

_getval?

TRANGE

  _getval:

NOP

           MOVA,R6

           MOVB,R7

           RET

           END

做成一个单独的ASM文件,然后调用

13楼:

>>参与讨论

作者:

lhkjg于2005-5-810:

24:

00发布:

我也一直在学混编,我知道HT里面的混编非常的简单

但是C51里面我也搞了好多次就是不能编译,不知道哪里有这样的书可以肯肯!

还有就是汇编里面如何运用C里面定义的变量!

如果是函数是不是还需要“进站”“出站”什么的?

14楼:

>>参与讨论

作者:

wsj0902于2005-5-810:

42:

00发布:

刚学!

未入门!

一点愚见!

是不是要设计一个哑函数(作参数传递之用)!

我看书上有的例子在用寄存器传递参数时,用c设计了哑函数!

可能是为了参数传递的正确性吧!

如当用汇编编写某函数时,先用c写个哑函数,编译此哑函数!

看看参数传递是否正确!

ok的话!

再用汇编编写,然后再注释掉此哑函数

15楼:

>>参与讨论

作者:

wsj0902于2005-5-810:

46:

00发布:

c和汇编很重要的一点就是参数的传递!

否则很容易出错!

 

16楼:

>>参与讨论

作者:

manu2于2005-5-813:

51:

00发布:

你可以这样写

先用c写一个空函数,在开头写上#pragmaSRC(111.a51),写完后编译,然后再去编辑111.a51文件,把函数内容替换成你需要的就行了

17楼:

>>参与讨论

作者:

cyhwxm于2005-5-814:

23:

00发布:

关键是参数的传递

关键是参数的传递,即实参与返回值都是用寄存器传递的,搞清楚参数的传递原则就好办了,不知道我说的对否,请高人指点!

18楼:

>>参与讨论

作者:

duckcp于2005-5-815:

35:

00发布:

你用什么编译

wave一定要汇编用单独ASM文件,你的汇编好险就是有问题,没定义变量长,wave网站有例程,下载了看看格式,keil不一样,我没用过

19楼:

>>参与讨论

作者:

netscaner于2005-5-816:

30:

00发布:

在搜索引擎中输入"C51汇编混合编译",就可以找到答案了

 

20楼:

>>参与讨论

作者:

leonyang于2005-5-822:

17:

00发布:

谢谢各位了,总结一下。

小弟已经攻克了

现在将我的方法说明如下,供大家讨论。

1)ASM文件一定要单独编写,但是应该与C51的文件处于同一工程文件下。

2)C51中的注意事项:

    声明方法:

externuCHARASM_NAME(1st,2ed,3rd);

        调用方法:

uCHARindata=ASM_NAME(.......);

3)汇编的编写:

    PUBLIC_ASMNAME

        ASMNAMEPSEGMENTCODE

        RSGE   ASMNAME

        USING0

        _ASMNAME:

MOVA,R7     

                ;ASMCODEHERE

                  MOVR7,A     ;RESULEINACC,RETURNIT

                RET

                END

4)参数传递:

 CHAR   int    float    pointer

        1st   r7    r6r7     r4~r7   r1r2r3

        2ed   r5    r4r5     r4~r7   r123

        3rd   r3    rr2r3    no      r123

最后,感谢大家的回复。

还是好人多啊,呵呵

21楼:

>>参与讨论

作者:

thankw于2005-5-98:

56:

00发布:

在A51文件最开始要加一句---NAME模块名--声明一个ASM模块

模块名就是文件名字

22楼:

>>参与讨论

作者:

enbed于2005-5-99:

04:

00发布:

可是,你用汇编写驱动,不一定比KEIL厉害了.

如果真的做东西,不推荐这么用了.

1.需要学的东西,比你学C51的代价高.

2.即使你调试通过,完成功能,以后升级,维护代价过高.

3.KEIL的C不是标准C,跟汇编比,效力还可以的.所以没有必要这么麻烦,你又没有特别的要求哦.

4.如果你实在要用,小心堆栈指针.

23楼:

>>参与讨论

作者:

sunny_dg于2005-5-99:

09:

00发布:

方法2

有时在C51程序中需要嵌入一些汇编代码,这时当然可以用通常的作法:

按照C51与汇编的接口写一个汇编函数,然后在C51程序中调用该函数。

(此种方法正如楼主所列)

下面介绍直接嵌入汇编代码的方法:

1、在C文件中要嵌入汇编代码片以如下方式加入汇编代码:

#pragmaASM

;AssemblerCodeHere

#pragmaENDASM

2、在Project窗口中包含汇编代码的C文件上右键,选择“Optionsfor...”,点击右

边的“GenerateAssemblerSRCFile”和“AssembleSRCFile”,使检查框由灰色变成黑

色(有效)状态;

3、根据选择的编译模式,把相应的库文件(如Small模式时,是Keil\C51

\Lib\C51S.Lib)加入工程中,该文件必须作为工程的最后文件;

4、编译,即可生成目标代码。

24楼:

>>参与讨论

作者:

leonyang于2005-5-920:

15:

00发布:

re

大家的讨论在下均一一领教啦,谢了。

  主要是本人一直是用汇编的,(很久前用过TRUBOC)一时间要用C51,没有办法,只能采用这个办法,C51的一些技巧应该没有汇编熟悉,用起来反而不顺手。

  是的,混合编译要冒一定的风险,对堆栈和关键寄存器的保护十分关键。

只能硬着头皮上啦。

  关于“方法2”,本人有过尝试,要反复编译,由此确定变量的地址,再

修改嵌入的汇编语句,传出参数。

25楼:

>>参与讨论

作者:

o_wild于2005-5-1117:

53:

00发布:

试试看

把汇编程序存为*.a51,连同*.c文件一起加入sourceGROUP.

26楼:

>>参与讨论

作者:

dengland于2005-5-1221:

35:

00发布:

这样能调用的吗?

 

27楼:

>>参与讨论

作者:

aoshi于2005-5-1413:

01:

00发布:

使用嵌入汇编或将两个分到两个文件中都可以

但在同一个文件不行

28楼:

>>参与讨论

作者:

aoshi于2005-5-1413:

37:

00发布:

re

可以用嵌入汇编啊

29楼:

>>参与讨论

作者:

fushaobing于2005-5-1413:

59:

00发布:

TOleonyang;

祝贺你!

30楼:

>>参与讨论

作者:

joypan于2005-5-1414:

14:

00发布:

高手快留言

哪位高手有料,快发表呀,别做图书馆管理员。

31楼:

>>参与讨论

作者:

zhu1982lin于2005-5-1418:

03:

00发布:

这是我以前在网上下的文章,希望对你有用

如何在KEILC51(v6.21)中调用汇编函数的一个示例[ycong_kuang]

有关c51调用汇编的方法已经有很多帖子讲到,但是一般只讲要点,很少有对整个过程作详细描述,对于初学者是不够的,这里笔者

通过一个简单例子对这个过程进行描述,希望能对初学者有所帮助。

几年来,在这个论坛里笔者得到很多热心人指导,因此也希望

藉此尽一点绵薄之力。

在这个例子里,阐述了编写c51程序调用汇编函数的一种方法,这个外部函数的入口参数是一个字符型变量和一个位变量,返回值是

一个整型变量。

例中,先用c51写出这个函数的主体,然后用SRC控制指令编译产生asm文件,进一步修改这个asm文件就得到我们所

要的汇编函数。

该方法让编译器自动完成各种段的安排,提高了汇编程序的编写效率。

step1.按写普通c51程序方法,建立工程,在里面导入main.c文件和CFUNC.c文件。

相关文件如下:

//main.c文件

#include

#defineuCHARunsignedCHAR

#defineuintunsignedint

externuintAFUNC(uCHARv_achr,bitv_bflag);

voidmain()

{

    bitBFLAG;

    uCHARmav_chr;

    uint    mvintrslt;

    mav_chr=0xd4;BFLAG=1;

    mvintrslt=AFUNC(mav_chr,BFLAG);

}

//CFUNC.c文件

#defineuCHARunsignedCHAR

#defineuintunsignedint

uintAFUNC(uCHARv_achr,bitv_bflag)

{

    uCHARtmp_vchr;

    uint  tp_vint;

    tmp_vchr=v_achr;

    tp_vint=(uint)v_bflag;

    returntmp_vchr+(tp_vint<<8);

}

step2.在Project窗口中包含汇编代码的C文件上右键,选择“Optionsfor...”,点击右边的“GenerateAssemblerSRC

        File”和“AssembleSRCFile”,使检查框由灰色变成黑色(有效)状态;

step3.根据选择的编译模式,把相应的库文件(如Small模式时,是Keil\C51\Lib\C51S.Lib)加入工程中,该文件必须作为工

       程的最后文件;

step4.build这个工程后将会产生一个CFUNC.SRC的文件,将这个文件改名为CFUNC.A51(也可以通过编译选项直接产生CFUNC.A51文

       件),然后在工程里去掉库文件(如C51S.Lib)和CFUNC.c,而将CFUNC.A51添加到工程里。

//CFUNC.SRC文件如下

.\CFUNC.SRCgeneratedfrom:

CFUNC.c

NAMECFUNC

?

PR?

_AFUNC?

CFUNC     SEGMENTCODE

?

BI?

_AFUNC?

CFUNC     SEGMENTBITOVERLAYABLE

    PUBLIC    ?

_AFUNC?

BIT

    PUBLIC    _AFUNC

    RSEG  ?

BI?

_AFUNC?

CFUNC

?

_AFUNC?

BIT:

    v_bflag?

041:

   DBIT   1

;#defineuCHARunsignedCHAR

;#defineuintunsignedint

;

;uintAFUNC(uCHARv_achr,bitv_bflag)

    RSEG  ?

PR?

_AFUNC?

CFUNC

_AFUNC:

    USING    0

            ;SOURCELINE#5

;----Variable'v_achr?

040'assignedtoRegister'R7'----

;{

            ;SOURCELINE#6

;     uCHARtmp_vchr;

;     uint    tp_vint;

;

;     tmp_vchr=v_achr;

            ;SOURCELINE#10

;----Variable'tmp_vchr?

042'assignedtoRegister'R5'----

    MOV      R5,AR7

;     tp_vint=(uint)v_bflag;

            ;SOURCELINE#11

    MOV      C,v_bflag?

041

    CLR      A

    RLC      A

;----Variable'tp_vint?

043'assignedtoRegister'R6/R7'----

;     returntmp_vchr+(tp_vint<<8);

            ;SOURCELINE#12

    MOV      R6,A

    MOV      R4,#00H

    CLR      A

    ADD      A,R5

    MOV      R7,A

    MOV      A,R4

    ADDC     A,R6

    MOV      R6,A

;}

            ;SOURCELINE#13

?

C0001:

    RET

;ENDOF_AFUNC

    END

step5.检查main.c的“GenerateAssemblerSRCFile”和“AssembleSRCFile”是否有效,若是有效则点击使检查框变成无效状

       态;再次build这个工程,到此你已经得到汇编函数的主体,修改函数里面的汇编代码就得到你所需的汇编函数了。

参考文献:

  1.徐爱钧,彭秀华。

单片机高级语言C51windows环境编程与应用,电子工业出版社

  ,  C51编程:

关于在KEILC51中直接嵌入汇编。

帖子编号:

83838发表用户:

Youth

  .................................................................................................................

                                 keil中汇编函数调用c51函数[ycong_kuang]

在keil的写法可参考89852帖子,具体如下:

与89852帖子相比,第一步在工程里多了一个被汇编调用的c51的函数文件(c51func.c),至于汇编函数还是先用c51编写出主体

(a51func.c),这样汇编程序接口和段都交给编译器处理,你只管在编译成汇编代码后按你的要求改写汇编代码就行了。

例程如下:

//main.c

#include

#defineuCHARunsignedCHAR

#defineuintunsignedint

externuintAFUNC(uCHARv_achr,bitv_bflag);

voidmain()

{

    bitBFLAG;

    uCHARmav_chr;

    uint    mvintrslt;

    mav_chr=0xd4;BFLAG=1;

    mvintrslt=AFUNC(mav_chr,BFLAG);

}

//a51FUNC.c

#defineuCHARunsignedCHAR

#defineuintunsignedint

externuintCFUNC(uint);

uintAFUNC(uCHARv_achr,bitv_bflag)    //c51写的汇编函数,最终要变成汇编代码

{

    uCHARtmp_vchr;

    uint  tp_vint;

    tmp_vchr=v_achr;

    tp_vint=(uint)v_bflag;

    returnCFUNC(tp_vint);             //这里调用一个c51函数

}

//c51FUNC.c

#defineuCHARunsignedCHAR

#defineuintunsignedint

uintCFUNC(uintv_int)                //被汇编函数调用c51函数

{

    returnv_int<<2;

}

第二步是按89852帖子的step2,3,4把用c51写的(汇编)函数变成a51文件(今天我试了一下step3可以不要)例程编译结果如

下:

;.\a51func.SRCgeneratedfrom:

a51func.c

NAME    A51FUNC

?

PR?

_AFUNC?

A51FUNC   SEGMENTCODE

?

DT?

_AFUNC?

A51FUNC   SEGMENTDATAOVERLAYABLE

?

BI?

_AFUNC?

A51FUNC   SEGMENTBITOVERLAYABLE

    EXTRN    CODE

32楼:

>>参与讨论

作者:

leonyang于2005-5-1421:

56:

00发布:

怪了,再总结先。

我记得我回过一篇帖,总结了在下的成功经验,不见了。

难道我

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1