Keil C系列之编译器介绍(1)
1 Cx51编译器的介绍
C编程语言是一种通用编程语言,它提供了代码效率、结构化编程元素和丰富的操作符集。C语言不是一门很大的语言,也不是为任何特定的应用领域而设计的。C语言的通用性和它的无限制相结合,使得C语言方便而有效地解决了各种各样的软件任务。与其他更专业的语言相比,使用c语言可以更容易、更有效地解决许多应用程序。
Cx51优化C编译器是C语言美国国家标准协会(nSI)标准的完整实现。Cx51编译器不是一个适用于os目标的通用C编译器。它是一个基础实现,致力于为8051微处理器生成极其快速和紧凑的代码。Cx5编译器为您提供了C语言编程的灵活性以及汇编语言的代码效率和速度。c语言本身不能执行通常需要操作系统干预的操作(例如输入和输出)。相反,这些功能是作为标准库的一部分提供的。因为这些函数与语言本身是分离的,所以c特别适合于生成可在各种平台上移植的代码。由于Cx51编译器是一个交叉编译器,因此C编程语言和标准库的某些方面被修改或增强,以解决嵌入式目标处理器的特性。
1)如下为介绍C语言的书籍:
The C Programming Language, Second Edition
Kernighan & Ritchie
Prentice-Hall, Inc.
ISBN 0-13-110370-9
C: A Reference Manual, Second Edition
Harbison & Steel
Prentice-Hall Software Series
ISBN 0-13-109810-1
C and the 8051: Programming and Multitasking
Schultz
P T R Prentice-Hall, Inc.
ISBN 0-13-753815-4
2)编译器支持的8051单片机及其衍生的器件
8051系列是发展最快的微控制器架构之一。目前有超过500种来自各种芯片供应商的器件变体可供选择。新的扩展8051芯片,如Phlips ocsMx架构,专门用于具有几兆字节代码和数据空间的大型应用程序。为了对8051内核衍生产品提供最佳支持,Keil提供了几个开发工具,如下表所示。一种新的输出文件格式(**OMF2**)允许直接支持多达16M的代码和数据空间。Cx51编译器是C51的一个变体,这是为新的飞利浦80C51MX架构设计的编译器。
2 程序编译
本章将讨论编译器指令的使用和如何进行C 源码的编译。将分为三部分内容进行介绍:
1、指示Cx51编译器生成 listing file
2、控制对象文件中包含的信息量。
3、指定优化级别和内存模型。
1)环境设置
如果使用命令行运行编译器,需要先配置好环境变量才能正常使用,配置内容如下:
2)命令提示符格式
C51 sourcefile 〚directives...〛
C51 @commandfile
或者
CX51 sourcefile 〚directives...〛
CX51 @commandfile
**sourcefile** Is the name of the source program you want to compile.
**directives** Are directives that control the operation of the compiler. Refer to Directives for a detailed list of the available directives.
**commandfile** Is the name of a command input file that may contain the sourcefile and directives. A commandfile is commonly used when the compiler command line is complex or exceeds the limits of the Windows command prompt. The maximum size of the command input file is limited to 64KB.
例如如下的编译指令:
C51 SAMPLE.C DEBUG CODE PREPRINT
2)ERRORLEVEL
编译后,将检测到的错误和警告的数量输出到屏幕上。Cx51编译器设置ERRORLEVEL来指示编译的状态。取值如下表所示
###编译后输出文件
编译时需使用对应编译指令才能产生对应文件
Listing 文件
编译器清单文件包含大量关于编译过程的信息。它由许多部分组成,下面将按顺序描述每个部分它们出现在文件中。
Page Header
C51 COMPILER V7.20 MEASURE 10/01/2004 14:05:05 PAGE 1
Command Line
C51 COMPILER V7.20, COMPILATION OF MODULE MEASURE
OBJECT MODULE PLACED IN Measure.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE Measure.c HOLD(128,
-0,0) OPTIMIZE(9,SPEED) BROWSE DEBUG OBJECT
-EXTEND CODE LISTINCLUDE SYMBOLS
Source Code
可以使用COND指令在源代码列表中包含所有条件代码(#if块中的代码)。NOCOND指令可用于从清单文件中排除未编译的条件代码块。也可以使用LISTINCLUDE指令在源代码列表中包含#include文件的内容。默认情况下,#include内容不会在清单文件中输出。
53 char code ERROR [] = "\n*** ERROR: %s\n";
54
55 #define PERIOD -250
56 #define WRONGINDEX 0xffff
57
58
59 /* The following function is called from */
60 /* the interrupt service routine. */
61 /* Save current measurements in save_record */
62
63
64 #pragma REGISTERBANK (1)
65
66 static void save_current_measurements (void) {
67 1 save_record[sindex++] = current;
68 1 if (sindex == SCNT) sindex = 0;
69 1 if (sindex == savefirst) {
70 2 if (++savefirst == SCNT) savefirst = 0;
71 2 }
72 1 }
73
74
75 /* Timer 0 interrupt service function */
76 /* executes each 250 usec @ 12 MHz Crystal Clock */
77
78 void timer0 (void) interrupt 1 using 1 {
79 1
80 1 unsigned char i;
81 1
82 1 if (measurement_interval) {
83 2 save_current_measurements ();
84 2 measurement_interval = 0;
85 2 }
Assembly Listing
汇编清单包含编译器为c源代码生成的汇编代码。CODE指令可用于汇编代码列表输出。
; FUNCTION save_current_measurements (BEGIN)
; SOURCE LINE # 66
; SOURCE LINE # 67
0000 0500 R INC sindex+01H
0002 E500 R MOV A,sindex+01H
0004 AE00 R MOV R6,sindex
0006 7002 JNZ ?C0064
0008 0500 R INC sindex
000A ?C0064:
000A 14 DEC A
000B FF MOV R7,A
000C 120000 R LCALL L?0079
000F A809 MOV R0,AR1
0011 FC MOV R4,A
0012 7D01 MOV R5,#01H
0014 120000 R LCALL L?0077
; SOURCE LINE # 68
0017 E500 R MOV A,sindex+01H
0019 B4E80A CJNE A,#0E8H,?C0001
001C E500 R MOV A,sindex
001E B40205 CJNE A,#02H,?C0001
0021 E4 CLR A
0022 F500 R MOV sindex,A
0024 F500 R MOV sindex+01H,A
0026 ?C0001:
; SOURCE LINE # 69
0026 E500 R MOV A,sindex+01H
0028 B5001B R CJNE A,savefirst+01H,?C0004
002B E500 R MOV A,sindex
002D B50016 R CJNE A,savefirst,?C0004
Symbol Listing
符号清单包含编译后的源文件中有关程序符号的符号信息。包括符号名称、分类(SFR、structure、typedef、static、public、auto、extern)、内存空间、数据类型、偏移量和字节大小。SYMBOLS指令可用于符号列表输出。
NAME CLASS MSPACE TYPE OFFSET SIZE
==== ===== ====== ==== ====== ====
P4 . . . . . . . . . . . . SFR DATA U_CHAR 00E8H 1
P5 . . . . . . . . . . . . SFR DATA U_CHAR 00F8H 1
BD . . . . . . . . . . . . ABSBIT ----- BIT 00DFH 1
current. . . . . . . . . . PUBLIC DATA STRUCT 0000H 11
ERROR. . . . . . . . . . . PUBLIC CODE ARRAY 0416H 16
sindex . . . . . . . . . . PUBLIC DATA U_INT 000BH 2
clock. . . . . . . . . . . * TAG * ----- STRUCT ----- 5
hour . . . . . . . . . . MEMBER ----- U_CHAR 0000H 1
min. . . . . . . . . . . MEMBER ----- U_CHAR 0001H 1
sec. . . . . . . . . . . MEMBER ----- U_CHAR 0002H 1
msec . . . . . . . . . . MEMBER ----- U_INT 0003H 2
size_t . . . . . . . . . . TYPEDEF ----- U_INT ----- 2
menu . . . . . . . . . . . STATIC CODE ARRAY 00C7H 847
ADCON. . . . . . . . . . . SFR DATA U_CHAR 00D8H 1
mdisplay . . . . . . . . . STATIC DATA BIT 0001H 1
interval . . . . . . . . . PUBLIC DATA STRUCT 0014H 4
interval . . . . . . . . . * TAG * ----- STRUCT ----- 4
min. . . . . . . . . . . MEMBER ----- U_CHAR 0000H 1
sec. . . . . . . . . . . MEMBER ----- U_CHAR 0001H 1
msec . . . . . . . . . . MEMBER ----- U_INT 0002H 2
wchar_t. . . . . . . . . . TYPEDEF ----- CHAR ----- 1
_getkey. . . . . . . . . . EXTERN CODE PROC ----- -----
BSY. . . . . . . . . . . . ABSBIT ----- BIT 00DCH 1
_toupper . . . . . . . . . EXTERN CODE PROC ----- -----
_printf. . . . . . . . . . EXTERN CODE PROC ----- -----
_set_interval. . . . . . . EXTERN CODE PROC ----- -----
_read_index. . . . . . . . STATIC CODE PROC 0000H -----
buffer . . . . . . . . . AUTO DATA PTR 0000H 3
index. . . . . . . . . . AUTO DATA INT 0003H 2
args . . . . . . . . . . * REG * DATA U_CHAR 0007H 1
measurement_interval . . . STATIC DATA BIT 0002H 1
Module Information
模块信息提供了源文件定义的初始化和未初始化内存区域的大小。
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 902 ----
CONSTANT SIZE = 1062 ----
XDATA SIZE = 8184 ----
PDATA SIZE = ---- ----
DATA SIZE = 24 8
IDATA SIZE = ---- 15
BIT SIZE = 3 ----
END OF MODULE INFORMATION.
Warnings and Errors
编译时遇到的问题可能会导致错误和/或警告,这些错误和/或警告会输出到屏幕和清单文件。有关错误和的详细信息,请参阅Error message。
Object (OBJ) File
Object (OBJ)文件是C51编译器生成OMF51或OMF2对象格式的目标对象(. obj)文件,以响应各种C语言语句和其他指令。OBJECT指令指定了目标文件的名称(默认为该指令),而NOOBJECT指令抑制了目标文件的输出。目标文件不仅仅是为C源代码生成的程序集的二进制表示。它是一个特殊格式的文件,包含符号信息、目标代码、调试信息、库引用等数据记录。下面是存储在object文件中的一些细节。
-
为全局变量预留内存。
-
公共符号(变量和函数)名称。
-
外部符号(变量和函数)引用。
-
要链接的库文件。
-
调试信息,以帮助同步源代码行与目标代码。
存储在object文件中的大多数对象代码都不是绝对的。它可以被链接器定位到任何适当的地址。对外部变量和函数的引用由编译器设置为地址0。链接器固定所有引用。由于这些原因,编译器生成的目标代码不能按原样执行。它必须在执行之前被链接。对象文件中存储的细节级别使得模拟器(如Keil Vision Simulator)、调试器(如Keil uVision Target Debugger)和模拟器可以加载你的程序,并提供完整的符号、源级调试功能。 请注意object文件提供了对原始源代码中行号的引用。它不包括原始源代码。源级调试要求调试器能够访问原始源代码。
Preprocessor (I) File
使用PREPRINT编译命令可以生成输出预处理文件。对预处理输出文件,常用于检查宏或者条件预处理是否正常
如:
#define defIt(x) char x[] = #x
void main (void)
{
defIt(asdf);
}
其生成的预处理输出文件为:
#line 1 "main.c" /0
void main (void)
{
char asdf[] = "asdf";
}
Source (SRC) File
编译器可以从一个有效的C源文件生成一个汇编源文件(. src)。有关如何使用该指令的信息,请参阅SRC指令。
创建汇编源文件有以下几个原因:
- 使用ASM和ENDASM指令将内联程序集添加到C函数中。
- 手动优化编译器的汇编输出。
- 正在用汇编代码编写一个例程,并希望在C中创建函数和参数的原型。
不管创建源文件的原因是什么,所需的步骤总是相同的:
- 创建一个C源文件。
- 添加任何必需的内联汇编指令。
- 使用SRC指令编译。
- 重命名. src文件,使其不会被原始C源代码的后续编译所覆盖(如果需要的话)。
- 对创建的汇编程序源文件进行更改。
- 使用汇编程序进行组装。
请注意当使用SRC指令时,编译器输出一个汇编源文件(.SRC)。没有输出object (. ob)文件。一旦C源文件转换为汇编程序源文件,c符号和源级调试就不可用。