ASM5无参数化调用C51函数的实现
MCS -51系列单片机在目前和今后的相当一段时间内都将是我国的单片机主流机种。但在早期的开发过程中,程序员不得不从深奥的汇编语言开始摸索,同时要求开发人员对硬件亦有相当的子解。相比而言,专用8051系列单片机设计的Franklin C51语言是一种通用的高级结构化的程序设计语言。入门容易,程序可读性强,调试、移植都很方便,故开发效率高,尤其在数值运算处理方便具有很大的优势(这正是ASM51汇编语言的薄弱环节)。不过,C语言虽然也可对计算机的硬件系统进行操作,但在处理特殊I/O口和中断向量方面,不如汇编那样直接、有效。因而,在效率为重的今天,将ASM51汇编与C51语言结合起来,充分发挥各自的优势,无疑是单片机开发人员的最佳选择。
1 汇编与C51的混合编程
一般的做法都是利用C51上手容易、便于理解的优势来编写主程序,在C51语言不便处理或者效率比较低时调用汇编函数。考虑到MCS-51(尤其是8031 内部的资源配置情况:可用的RAM不到256字节,5个固定地址的有限中断源,4个8位并口中实际可作I/O口的只有P1口。因而要求开发都对单片机的内部结构有清楚的了解,并尽可能地统筹安排这些资源。事实也证明,不理解汇编语言是很难写出高效程序的。故笔者的观点是利用汇编语言对I/O接口、中断向量及程序空间分配的茂大优势,让程序员对MCS-51内的第一个字节甚至是每一比特(可位寻址的空间)全部进行统筹安排,设计好各个程序模块,包括I/O口地址和中断向量地址的处理;同时在具体的数据处理、通信等不需要过多与硬件直接打交道的程序模块中,充分利用C51语言强大高效的编程能力。
最后的关键是如何让汇编模块能正确识别C51函数并调用它来完成相应的功能。ASM51汇编与C51 语言之间的调用约定并不简单,而且各种编译器使用的约定不尽相同,甚至还依赖于程序所选择的大、中、小存储模式。通常每个需传递的参数按调用顺序和类型分别由约定的寄存器来传递。如果参数过多或者无足够寄存器可用时,参数的传递将在固定持存储器区域内进行,相同类型的参数共享一个参数传递段,按参数调用顺序递增其存放地址,返回值也由约定的寄存器或地址段返回。由此可见程序调用的效率必将受到接口复杂度的影响。尽管目前的单片机仿真器已经提供了标准接口的全自动转换功能,减少了接口工作量,但在程序的调试及移植中,如果程序员不了解这些接口的各种约定,将对出现的错误不知所措。比如返回值不止一个时,编译器自己就无法正确完成接口配置。这里力荐一种简洁有效的调用方法——无参数化调用。
2 ASM51无参数化调用C51函数的实现原理
所谓的无参数化调用是指让C51子函数不带任何参数,这样就可以从根本上避开调用参数的传递和返回值的安排等繁琐易出错的问题,只需要简单地在汇编语言开头说明一下外部C51子函数(“EXTRN code(C51模块名称>)”)。至于C51函数中需要使用的外部参数值及其返回值,完全可以通过加入C51 的absacc.h>头文件来解决。
absacc.h>头文件中的函数原型为:
# define CBYTE((unsigned char *)0x50000L)
# define DBYTE ((unsigned char *)0x50000L)
# define PBYTE ((unsigned char *)0x50000L)
# define XBYTE((unsigned char *)0x50000L)
其中CBYTE定义为寻址CODE程序区;DBYTE定义为寻址DATA数据区;PBYTE定义为寻址相对于MOVX @R0"指令的分页数据XDATA区;XBYTE定义为寻址相对于MOVX @DPTR"指令的分布数据XDATA区。它们的类型决定了绝对地址空间的位置。
引进该头文件后,程序员就可以对8051系列单片机的存储器进行绝对地址的访问,把对参数值和返回值的操作转化为对存储器绝对地址的操作,像纯汇编操作一样,根本不用定义C51函数与汇编接口的参数和返回值的配置,从而提高了调用效率。具体做法是:先在 C51函数中定义好传递参数和返回值所需要的各个绝对地址(视程序员自己的空间配置而定),在其它汇编模块中将C51函数中将要使用的参数值放入这些绝对地址中,把被调用C51模块将输出的计算值(可以不止一个)也放入类似的绝对地址中。于是,当C51函数中需要使用某个参数值时,就直接从相应的绝对地址中读取该值;当别的汇编模块中需要使用C51函数返回值时,也直接对存放返回值的绝对地址进行读操作即可。下面以一个调试通过的汇编调用C51函数的简单程序为例进行具体说明。
3 ASM51无参数化调用C51函数的实现示例
该系统要示然而单片机根据实时采样输入的转速实现机车速度的测量,并可随键盘输入的车轮直径变化实时调整车速,最后将车速和轮径值都显
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)