如何在KEIL C51(v6.21) 中调用汇编函数的一个示例

发布者:柳絮轻风最新更新时间:2016-11-22 来源: eefocus关键字:KEIL  C51  调用汇编函数 手机看文章 扫描二维码
随时随地手机看文章

有关c51调用汇编的方法已经有很多帖子讲到,但是一般只讲要点,很少有对整个过程作详细描述,对于初学者是不够的,这里笔者通过一个简单例子对这个过程进行描述,希望能对初学者有所帮助。几年来,在这个论坛里笔者得到很多热心人指导,因此也希望藉此尽一点绵薄之力。

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

一个整型变量。例中,先用c51写出这个函数的主体,然后用SRC控制指令编译产生asm文件,进一步修改这个asm文件就得到我们所要的汇编函数。该方法让编译器自动完成各种段的安排,提高了汇编程序的编写效率。

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

相关文件如下:

//main.c文件

#include < reg51.h >

#define uchar unsigned char

#define uint unsigned int

extern uint AFUNC(uchar v_achr,bit v_bflag);

void main()

{

    bit BFLAG;

    uchar mav_chr;

    uint    mvintrslt;

    mav_chr=0xd4; BFLAG=1;

    mvintrslt=AFUNC(mav_chr,BFLAG);

}

//CFUNC.c文件

#define uchar unsigned char

#define uint unsigned int

uint AFUNC(uchar v_achr,bit v_bflag)

{

    uchar tmp_vchr;

    uint  tp_vint;

    tmp_vchr=v_achr;

    tp_vint=(uint)v_bflag;

    return tmp_vchr+(tp_vint<<8);

}

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

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

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

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

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

//CFUNC.SRC文件如下

.\CFUNC.SRC generated from: CFUNC.c

NAME CFUNC

?PR?_AFUNC?CFUNC     SEGMENT CODE

?BI?_AFUNC?CFUNC     SEGMENT BIT OVERLAYABLE

    PUBLIC    ?_AFUNC?BIT

    PUBLIC    _AFUNC

    RSEG  ?BI?_AFUNC?CFUNC

?_AFUNC?BIT:

    v_bflag?041:   DBIT   1

; #define uchar unsigned char

; #define uint unsigned int

;

; uint AFUNC(uchar v_achr,bit v_bflag)

    RSEG  ?PR?_AFUNC?CFUNC

_AFUNC:

    USING    0

            ; SOURCE LINE # 5

;---- Variable 'v_achr?040' assigned to Register 'R7' ----

; {

            ; SOURCE LINE # 6

;     uchar tmp_vchr;

;     uint    tp_vint;

;

;     tmp_vchr=v_achr;

            ; SOURCE LINE # 10

;---- Variable 'tmp_vchr?042' assigned to Register 'R5' ----

    MOV      R5,AR7

;     tp_vint=(uint)v_bflag;

            ; SOURCE LINE # 11

    MOV      C,v_bflag?041

    CLR      A

    RLC      A

;---- Variable 'tp_vint?043' assigned to Register 'R6/R7' ----

;     return tmp_vchr+(tp_vint<<8);

            ; SOURCE LINE # 12

    MOV      R6,A

    MOV      R4,#00H

    CLR      A

    ADD      A,R5

    MOV      R7,A

    MOV      A,R4

    ADDC     A,R6

    MOV      R6,A

; }

            ; SOURCE LINE # 13

?C0001:

    RET

; END OF _AFUNC

    END

step5. 检查main.c的“Generate Assembler SRC File”和“Assemble SRC File”是否有效,若是有效则点击使检查框变成无效状态;再次build这个工程,到此你已经得到汇编函数的主体,修改函数里面的汇编代码就得到你所需的汇编函数了。

参考文献:

  1.徐爱钧,彭秀华。单片机高级语言C51windows环境编程与应用,电子工业出版社

  2.www.c51bbs.com,  C51编程:关于在 KEIL C51 中直接嵌入汇编。。。帖子编号: 83838 发表用户:Youth

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

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

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

与89852帖子相比,第一步在工程里多了一个被汇编调用的c51的函数文件(c51func.c),至于汇编函数还是先用c51编写出主体(a51func.c),这样汇编程序接口和段都交给编译器处理,你只管在编译成汇编代码后按你的要求改写汇编代码就行了。

例程如下:

//main.c

#include < reg51.h >

#define uchar unsigned char

#define uint unsigned int

extern uint AFUNC(uchar v_achr,bit v_bflag);

void main()

{

    bit BFLAG;

    uchar mav_chr;

    uint    mvintrslt;

    mav_chr=0xd4; BFLAG=1;

    mvintrslt=AFUNC(mav_chr,BFLAG);

}

//a51FUNC.c

#define uchar unsigned char

#define uint unsigned int

extern uint CFUNC(uint);

uint AFUNC(uchar v_achr,bit v_bflag)    //c51写的汇编函数,最终要变成汇编代码

{

    uchar tmp_vchr;

    uint  tp_vint;

    tmp_vchr=v_achr;

    tp_vint=(uint)v_bflag;

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

}

//c51FUNC.c

#define uchar unsigned char

#define uint unsigned int

uint CFUNC(uint v_int)                //被汇编函数调用c51函数

{

    return v_int<<2;

}

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

; .\a51func.SRC generated from: a51func.c

NAME    A51FUNC

?PR?_AFUNC?A51FUNC   SEGMENT CODE

?DT?_AFUNC?A51FUNC   SEGMENT DATA OVERLAYABLE

?BI?_AFUNC?A51FUNC   SEGMENT BIT OVERLAYABLE

    EXTRN    CODE (_CFUNC)

    PUBLIC    ?_AFUNC?BIT

    PUBLIC    _AFUNC

    RSEG  ?DT?_AFUNC?A51FUNC

?_AFUNC?BYTE:

   tmp_vchr?042:   DS   1

    RSEG  ?BI?_AFUNC?A51FUNC

?_AFUNC?BIT:

    v_bflag?041:   DBIT   1

; //a51FUNC.c

;

; #define uchar unsigned char

; #define uint unsigned int

;

; extern uint CFUNC(uint);

;

; uint AFUNC(uchar v_achr,bit v_bflag)

    RSEG  ?PR?_AFUNC?A51FUNC

_AFUNC:        ;c51所写的函数产生的汇编代码从这里开始

    USING    0

            ; SOURCE LINE # 8

;---- Variable 'v_achr?040' assigned to Register 'R7' ----

; {

            ; SOURCE LINE # 9

;     uchar tmp_vchr;

;     uint  tp_vint;

;

;     tmp_vchr=v_achr;

            ; SOURCE LINE # 13

    MOV      tmp_vchr?042,R7

;     tp_vint=(uint)v_bflag;

            ; SOURCE LINE # 14

    MOV      C,v_bflag?041

    CLR      A

    MOV      R6,A

    RLC      A

    MOV      R7,A

;---- Variable 'tp_vint?043' assigned to Register 'R6/R7' ----

;      这里说明R6,R7内容就是tp_vint

;     return CFUNC(tp_vint);

            ; SOURCE LINE # 16

    LCALL    _CFUNC    ;这里调用了用c51写的函数

; }

            ; SOURCE LINE # 17

?C0001:

    RET

; END OF _AFUNC

    END

这个文件就是你的汇编函数所在文件,把函数里面的汇编代码修改成你所需的汇编函数就ok了。

建议参考 徐爱钧,彭秀华所写的《单片机高级语言C51windows环境编程与应用》或马忠梅所写的

单片机的c语言应用程序设计》有关混合语言编程有关章节

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

                                关于在 KEIL C51 中直接嵌入汇编。。。 [Youth]

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

按照 C51 与汇编的接口写一个汇编函数,然后在 C51 程序中调用该函数。(此种方法可在论坛里搜索,以前有很多帖子讲到,不再重复)

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

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

#pragma ASM

 ; Assembler Code Here

#pragma ENDASM

2、在 Project 窗口中包含汇编代码的 C 文件上右键,选择“Options for ...”,点击右边的“Generate Assembler SRC File”

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

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

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


关键字:KEIL  C51  调用汇编函数 引用地址:如何在KEIL C51(v6.21) 中调用汇编函数的一个示例

上一篇:uC/OS-II在C51上的移植步骤
下一篇:RS232串口驱动(C51)

推荐阅读最新更新时间:2024-03-16 15:21

C51的指针,试验
C51的指针,试验,===结果:成功 /*********************************************************************/ /* 试指针,假设TL0存在20H,TH0存在21H,下一个 TL0存在22H,TH0存在23H , 共存4组。 计算这4组数据的4次累加后和平均值,再分离存入W10,W11,W12,W13等4个8位寄存器 */ /*********************************************************************/ #include AT89X52.h #include intrins.h #inclu
[单片机]
<font color='red'>C51</font>的指针,试验
ASM51调用C51函数的实现
MCS-51系列单片机在目前和今后的相当一段时间内都将是我国的单片机主流机种。但在早期的开发过程中,程序员不得不从深奥的汇编语言开始摸索,同时要求开发人员对硬件亦有相当的子解。相比而言,专用8051系列单片机设计的Franklin C51语言是一种通用的高级结构化的程序设计语言。入门容易,程序可读性强,调试、移植都很方便,故开发效率高,尤其在数值运算处理方便具有很大的优势(这正是ASM51汇编语言的薄弱环节)。不过,C语言虽然也可对计算机的硬件系统进行操作,但在处理特殊I/O口和中断向量方面,不如汇编那样直接、有效。因而,在效率为重的今天,将ASM51汇编与C51语言结合起来,充分发挥各自的优势,无疑是单片机开发人员的最佳选
[单片机]
keil中勾选microlib使用printf
在keil (我用的是realview mdk3.11)建立ARM的工程时 其中有一项是选 use MicroLIB 由于对KEIL不是很熟悉,于是就查了查,得到了以下信息: microlib 是缺省 C 库的备选库。 它旨在与需要装入到极少量内存中的深层嵌入式应用程序配合使用。 这些应用程序不在操作系统中运行。 microlib 进行了高度优化以使代码变得很小。 它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。 某些库函数的运行速度也比较慢,例如,memcpy()。 与缺省 C 库之间的差异 microlib 与缺省 C 库之间的主要差异是: microlib 不符合 ISO C 库标准。 不支持某些 IS
[单片机]
<font color='red'>keil</font>中勾选microlib使用printf
keil常见错误和解决方法
1. Warning 280: i :unreferenced local variable 说明局部变量i 在函数中未作任何的存取操作。 解决方法消除函数中i 变量的宣告。 2. Warning 206: Music3 :missing function-prototype 说明Music3( )函数未作宣告或未作外部宣告所以无法给其他函数调用。 解决方法将叙述void Music3(void)写在程序的最前端作宣告如果是其他文件的函数则要写成extern void Music3(void),即作外部宣告。 3. Compling :C:8051MANN.C Error:318:can t open file beep
[单片机]
MSP432(Keil5)——8.oled驱动
今天给大家带来msp432的oled驱动,本次实验代码移植的中景园电子的优秀代码。 使用的oled是7线spi方式的,熟悉oled的也可以自行修改成iic。 oled.c // //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //中景园电子 //店铺地址:http://shop73023976.taobao.com/?spm=2013.1.0.0.M4PqC2 // // 文 件 名 : main.c // 版 本 号 : v2.0 // 作 者 : HuangKai // 生成日期 : 2014-0101 // 最近修改 : // 功能描述 : OLED 4接口演示例程(51系列) //
[单片机]
MSP432(<font color='red'>Keil</font>5)——8.oled驱动
C51单片机浮点数运算
第一,不知道你zhi的a和b是什么类型dao的,如果是定义成浮点型,那么,可以这样写: float f_Div = a/b; 如果两个有一个是整形的,那么,把整型强制转换成浮点型: float f_Div = (float)a/(float)b; 注意,那个f_Div变量必须是float型,才能有小数产生 第二,你要进行显示,肯定要把各个位都取出来,这里面肯定有一个取模运算,就是 % , 对于浮点型,不运行取模运算的,所以,你必须把浮点型转换成整型,但是,不能强制转换, 比如: unsigned int I_Div = (unsigned int)f_Div;这是不可以的,你的小数部分就没有了. 所以,你必须要放大一定的倍数,根据
[单片机]
STM32 KEIL软件设置程序烧写起始地址选择
STM32系列的mcu,这儿以cortex-M4为例,我们在线调试时,一般会设置程序烧写起始地址和大小。这个大小一般是0x08000000,也就是内部flash的映射地址。不过有些产品是从0x08020000开始的,这是为什么呢?是因为在0x08000000-0x08020000这段空间放的是引导程序,也就是引导程序是从0x08000000开始存放,一般而言,引导程序最终也是要跳转到主app执行的,对于我们这儿而言,就是引导程序会跳转到0x08020000继续执行,而主工程代码是从0x08020000开始存放的,所以就这样串联起来了。 这儿可以看到我们设置的程序烧写的地址和大小,这个的设置是要和use memory layou
[单片机]
STM32 <font color='red'>KEIL</font>软件设置程序烧写起始地址选择
Proteus软件仿真与Keil的51单片机系统设计
  1 概述   随着半导体技术的飞速发展,以及移动通信、网络技术、多媒体技术在嵌入式系统设计中的应用,单片机从4位、8位、16位到32位,其发展历程一直受到广大电子爱好者的极大关注。单片机功能越来越强大,价格却不断下降的优势无疑成为嵌入式系统方案设计的首选,同时单片机应用领域的扩大也使得更多人加入到基于单片机系统的开发行列中,推动着单片机技术的创新进步。   然而传统的单片机系统开发除了需要购置诸如仿真器、编程器、示波器等价格不菲的电子设备外,开发过程也较繁琐。如图1所示,用户程序需要在硬件完成的情况下才能进行联调,如果在调试过程中发现需修改硬件,则要重新制板。因此无论从硬件成本还是开发周期来看,其高风险、低效率的特性显露无
[单片机]
Proteus软件仿真与<font color='red'>Keil</font>的51单片机系统设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved