“长缨8 STC编译器”是笔者为STC8系列单片机研制的C语言编译器。长缨8编译器是基于“STC80351指令集”开发的,“A351”是80351指令集汇编语言的名称,C351是长缨8支持的C语言规范的名称。目前的长缨8编译器V3.x版支持STC 80351的L0和L1等级指令集。 研制长缨8编译器的目的是为新的采用80351指令集的STC32位单片机的软件工具链进行先行研究,因此并没有计划支持C51语言的全部特征和规范。C351语言规范是Keil的C51的一个子集,子集的大小以能够用C351语言开发出一个8位单片机上的RTOS为标准。 本文将用5个范例程序来介绍C351与C51语言的兼容性,介绍A351与A51语言的兼容性,介绍A351中的80351汇编语言格式以及介绍C351编程方法。范例在文末的附件里。 一、C351语法是C51的一个子集 (1)本文的范例是连接在P2端口上的8个LED灯交替闪烁。下图是范例1的C51主程序: (2)本文的范例是用Keil的IDE项目组织的,可以直接使用C51编译。长缨8是一个独立的EXE文件,需要用MakeFile的方法来编译Keil的项目。下图四本范例的子目录文件列表: 双击其中的“长缨8_MakeFile.bat”批处理文件就可以对项目进行编译。目录中的“DEMO_STC8H.uvproj.MSG”是长缨8编译器生成的“编译信息”文件,这是一个文本文件,包含编译过程中出现的提示、警告、出错等信息。如果使用的是STC的IDE,这些信息将同步地显示在IDE信息框中。下图是编译成功后的内容: (3)长缨8作为研究版编译器,C351只支持C51中的简单数据结构、简单语句和简单表达式。对于范例1这样简单的C51程序,不需要做任何简化修改就使用长缨8编译器编译通过,生成正确运行的代码。 二、A351语法是A51的超集 (4)STC 80351-L0指令集是Intel8051指令集全集。STC 80351-L1指令集则进一步包含了16位、32位的运算和内存操作。长缨8 STC编译器既支持STC 80351-L0指令集,也支持STC 80351-L1指令集。A351支持A51的全部汇编功能和部分宏语言功能。
(5)Intel 8051指令集共有111条指令,范例2以A51汇编的形式给出了这些指令的实例,下图是范例程序开头的部分: 分别用Keil和长缨8对范例进行编译,对生成的HEX文件进行比较可以看到所有指令对应的代码完全一致,A351实现了对A51的全兼容。 (6)范例3是用A51汇编语言实现的范例1的P2端口LED灯交替闪烁效果的程序。分别用Keil和长缨8对范例进行编译,对生成的HEX文件进行比较可以看到两者对应的代码完全一致,A351实现了对A51的全兼容。 (7)范例4是用A351汇编语言实现的范例1的P2端口LED灯交替闪烁效果的程序。下图是其中延时函数的部分
其中“AX”和“BX”是两个16位的寄存器,利用两层循环实现软件延时。 (8)上面A351程序涉及到STC80351-L1指令集的指令有:“MVR”指令将右操作数的内容传送给左寄存器,“DECS”指令可以对8/16/32位的寄存器做减1操作,“IS_TRUE”指令判断操作数是否为零。 (9)由于Keil的IDE是主流的STC单片机集成开发环境,而STC 80351指令集的A351汇编语言尚未被C51/C251编译器接受,因此A351/C351语言特别增加了语法元素“配对的忽略符”:第25行的“/*{”和第54行的“}*/”: 在A351/C351语言中,起始忽略符“/*{”用在程序行的开头,C351/A351编译器将忽略该行程序。第25行中的下一个“A351”指明下面的程序按照A351汇编语言语法来编译。在A351/C351语言中,结束忽略符“}*/”用在程序行的开头,后面不要写其他内容,单独占一行程序。 (10)配对的“忽略符”在程序中的用途是“欺骗”C51/C251这样编译器,使得这些编译器认为配对的“忽略符”之间的程序是“块注释”的无关内容,就不会再进行语法检查。 三、C351编程的注意事项 (11)由于C351是C51的子集,因此C351的编程方法参考C51就行了。C351与C51最大的不同是C语言的复杂程度。C51语法是按专业人员的编程水平设计的,可以支持很复杂的语句结构。C351语法是按初学者的编程水平设计的,语法复杂程度控制在谭浩强C语言教材和大学生计算机等级C语言考试的水平上。 如果C351编译器出错而用户又看不出来错在哪里,那么往往是表达式太复杂造成的,用户可以试着引简单变量来简化程序。
(12)下图是范例5的主函数程序部分: 其中第23行和第45行是配对的“忽略符”程序。
(13)C351程序与C51/C251程序最大不同是允许将80351指令写在C语言程序中,就像上面的第29行、第36和37行程序一样。只不过在C351程序中这些指令仍然是C语言程序行,必须用分号结束。
|