1、函数内部混合编程
若想在C语言函数内部使用汇编语言,应使用以下Cx51编译器控制命令:
#pragma asm
;;; Assembly code
#pragma endasm
功能作用:
asm和endasm命令用于将其标记的汇编程序合并到.SRC文件中。这个带有asm和endasm块标记的源程序可看作是在线嵌入式汇编程序。从这点来说,此命令有些类似于#define命令。
具体实现:
(1)编译器设置及SRC文件的产生
.SRC文件在命令行编译模式下是使用SRC编译器控制命令产生的,在IDE环境中可以为需要产生SRC文件的C源文件设置特定选项:
l 右键单击Project Workspace下的文件标签
l 选择Options for file … 项,打开Options – Properties 页。
l 选中Generate Assembler SRC file 项
l 选中Assembler SRC file项
(2)添加库文件
根据选择的编译模式,把相应的库文件添加到工程下面,如在”small”模式下,需将”keil\c51\lib\c51s.lib”文件加入工程中。在Keil安装目录下的\C51\LIB\ 目录的LIB 文件如下:
C51S.LIB - 没有浮点运算的 Small model
C51C.LIB - 没有浮点运算的 Compact model
C51L.LIB - 没有浮点运算的 Large model
C51FPS.LIB - 带浮点运算的 Small model
C51FPC.LIB - 带浮点运算的 Compact model
C51FPL.LIB - 带浮点运算的 Large model
若未添加此库文件,则会提示” UNRESOLVED EXTERNAL SYMBOL ”警告。
如上设置后,编译,IDE会生成汇编源文件(.SRC)并由汇编器将此文件转化成目标文件(.OBJ)。
注意事项:
(1) 此时在汇编语言中虽可以加标签,以执行一些跳转类指令,但要注意不要与编译器产生的其他标签相同。
(2) 在遵循了Cx51参数的调用规则后,如在向该函数传递一char数时,编译器会将其编译成通过R7传递,此时在汇编语言若直接调用R7,会出现定义的变量(形参)未调用警告。
2、 函数外部混合编程
具体实现:
若要将一完整的函数编写为汇编语言,并可被其它函数调用,此时可以遵循如下过程:
(1) 源文件的建立
新建一C源文件如test.c,将其加入工程中,并写出要实现函数的的哑函数(即写出函数名及形参,不用给出具体实现,但最好写出简单调用形参的代码,使编译器不提示 ”定义的变量未被调用”的警告)。
(2) 从上” 具体过程 ”之(1)。
(3) 从上” 具体过程 ”之(2)。
(4) 编译文件,将test.c 从工程中移除,将生成的test.src文件改名,如test.a51。
(5) 将test.a51加入工程, 并在其内部书写具体要实现的汇编代码。
(6) 重新编译整体文件即可。
注意事项:
(1) 调用前一定要在所调用的文件内部声明该函数的存在,写法应同汇编语言的C函数实现一样,即test.c 中的函数名称。
关键字:C51 汇编语言 混合编程
引用地址:
C51与汇编语言混合编程之一
推荐阅读最新更新时间:2024-03-16 14:59
C51设计中几种精确延时方法
单片机因具有体积小、功能强、成本低以及便于实现分布式控制而有非常广泛的应用领域 。单片机开发者在编制各种应用程序时经常会遇到实现精确延时的问题,比如按键去抖、数据传输等操作都要在程序中插入一段或几段延时,时间从几十微秒到几秒。有时还要求有很高的精度,如使用单总线芯片DS18B20时,允许误差范围在十几微秒以内 ,否则,芯片无法工作。用51汇编语言写程序时,这种问题很容易得到解决,而目前开发嵌入式系统软件的主流工具为C语言,用C51写延时程序时需要一些技巧 。因此,在多年单片机开发经验的基础上,介绍几种实用的编制精确延时程序和计算程序执行时间的方法。 实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高C
[单片机]
如何让Keil MDK兼容Keil C51?
原来用51单片机,使用的是Keil C51 uVision V4.02;最近搞STM32,装了keilMDK uVision V4.23。 原来我是先装keilC51,后装keilMDK的,装在不同的目录里,装完之后不管是51工程还是stm32工程默认都会用keilMDK打开,这样打开51工程时会出错,所以要打开51的工程必须先打开keilC51程序,然后再程序里打开工程文件。 下面这个方法可以让keilMDK兼容51的工程,只要一个keil就都能编译51和stm32的工程了: 1、安装keilC51,并破解,安装目录 C:keilC51 2、安装keilMDK,并破解,安装目录 C:keilMDK 3、把 C:keilC
[单片机]
C51 的重入问题 WARNING L15: MULTIPLE CALL TO SEGMENT
1.第一种错误信息 ***WARNING L15: MULTIPLE CALL TO SEGMENT SEGMENT: ?PR?_WRITE_GMVLX1_REG?D_GMVLX1 CALLER1: ?PR?VSYNC_INTERRUPT?MAIN CALLER2: ?C_C51STARTUP 该警告表示连接器发现有一个函数可能会被主函数和一个中断服务程序(或者调用中断服务程序的函数)同时调用,或者同时被多个中断服务程序调用。 出现这种问题的原因之一是这个函数是不可重入性函数,当该函数运行时它可能会被一个中断打断,从而使得结果发生变化并可能会引起一些变量形式的冲突(即引起函数内一些数据的丢失,可重入性函
[单片机]
ARM裸机开发bootloader汇编语言
一、汇编语言概述 1、为什么要使用汇编 一般情况下我们不会用到汇编,但有两种情况下,我们要用到汇编。 1、启动代码。编写bootloader和内核时使用,主要是对cpu和内存进行初始化时使用,因为这个时候还没有c语言的环境(堆栈还没有建立),所以不能用c语言。 2、高效率的特殊需求。因为汇编语言的执行效率要高于c语言,所以对某些对效率要求高的程序要用到汇编,可以是汇编与c语言的混合编程。 2、汇编分类 1、ARM标准汇编,适用于windows平台下ARM公司开发的汇编器ADS。 2、GNU汇编,linux平台下GNU交叉编译工具链中的汇编器。它与ARM标准的一点不同是GNU汇编要在段标记符前加点,例如 .text。而AR
[单片机]
8051体系中Keil C51中对双数据指针的支持情况及代码生成
在8051体系中,数据指针DPTR作为一个特殊的16位寄存器,用于寻址64 KB的XDATA或CODE空间,通常它被当作一个16位指针,指向一个常数表。双数据指针可以改善同时有两个16位指针使用时的性能。作为一种增强特性,有许多8051派生型器件支持双数据指针。以宏晶科技STC89系列的产品为例,DPTR被增强为DPTR0和DPTR1两个,仍然使用原来的地址,用另外一个SFR AUXR1的0位DPS来切换。当DPS位为0时,所有对DPTR的操作使用DPTR0;当DPS位为1时,所有对DPTR的操作使用DPTR1。这样,通过一个简单的INC AUXR1指令,就可以来回切换两个数据指针。 1 Keil C51对双数据指针的支持情况 作为
[单片机]
C51/C52的定时器计数器与中断
一、定时器/计数器简介 设置等待时间,到达等待时间之后执行指定的硬件操作。 定时器最基本的功能就是定时,比如说定时发送串口数据,定时采集AD数据,如果将定时器和IO结合起来就可以实现非常丰富的功能,可以测量输入信号的脉冲宽度,可以产生PWM方波,定时器产生PWM控制电机状态是工业控制的普通。 ----------------------------------------------------------------------------------------------------------------------------------------------------------- 二、定时器/计数
[单片机]
c51两个定时器中断冲突_(六)定时器/计数器
一、简介 定时器和计数器是两个名字,但是原理上来说是一样的,都是对脉冲进行计数,区别在于时钟来源,如果来自内部时钟信号,由于内部时钟通常是比较准确的,所以是定时器,如果来自外部引脚,而外部引脚的信号并一定准确,则只对其进行计数,所以是计数器。接下来主要以定时器为主进行简单介绍,计数器类同。 二、时间计算 顾名思义,定时器肯定是和时间有关系的,那么时间是怎么计算的呢,我们以普通51内核为例。如下图(图片来自百度,我觉得他和51不符,所以改了下),通常一个指令周期=2X机器周期=12X时钟周期。而时钟周期又来自晶振。因此晶振频率确定后,那么各个时间也就确定了。 1. 计算内部指令周期 假设晶振频率是12MHz,那么机器周期=1
[单片机]
C51和汇编混合编程函数声明
最近看了一些C51的书,遇到了困难,查阅后终于理解了,望对大家有帮助! 先看个例子: ?PR?CLRME SEGMENT CODE; //在程序存储区中定义段 PUBLIC CLRME; //声明函数 RSEG ?PR?CLRME; //函数可被连接器放置在任何地方 CLRME: MOV R0,#7FH CLR A LOOP: MOV @R0,A DJNZ R0,LOOP RET END 只需给存放功能函数的段指定一个段名; ?PR? CLRME SEGMENT CODE;作用是在程序存储区中定义段,CLRME为段名,?PR?表示段位于程序存储区内 PUBLIC CLRME;作用是声明函数为公共函数 RSEG ?PR?CLRME
[单片机]