C51
C51
Information in this document is subject to change without notice and does not
represent a commitment on the part of the manufacturer. The software described
in this document is furnished under license agreement or nondisclosure
agreement and may be used or copied only in accordance with the terms of the
agreement. It is against the law to copy the software on any medium except as
specifically allowed in the license or nondisclosure agreement. The purchaser
may make one copy of the software for backup purposes. No part of this manual
may be reproduced or transmitted in any form or by any means, electronic or
mechanical, including photocopying, recording, or through information storage
and retrieval systems, for any purpose other than for the purchaser’s personal
use, without written permission.
Keil C51™, Keil CX51™, and µVision2 are a trademarks of Keil Elektronik
GmbH.
Microsoft® and Windows™ are trademarks or registered trademarks of
Microsoft Corporation.
IBM®, PC®, and PS/2® are registered trademarks of International Business
Machines Corporation.
Intel®, MCS® 51, MCS® 251, ASM-51®, and PL/M-51® are registered
trademarks of Intel Corporation.
Every effort was made to ensure accuracy in this manual and to give appropriate
credit to persons, companies, and trademarks referenced herein.
Keil Software — Cx51 Compiler User’s Guide 3
Preface
This manual describes how to use the Cx51 Optimizing C Compilers to compile
C programs for your target 8051 environment. The Cx51 Compiler package can
be used on all 8051 family processors and is executable under the Windows 32-
Bit command line prompt. This manual assumes that you are familiar with the
Windows operating system, know how to program 8051 processors, and have a
working knowledge of the C language.
NOTE
This manual uses the term Windows to refer to the 32-bit Windows Versions
Windows 95, Windows 98, Windows NT, and Windows 2000.
Many of the examples and descriptions in this manual discuss invoking the
compiler from the Windows command prompt. While this may not be applicable
to you if you are running Cx51 within an integrated development environment
like µVision2, examples in this manual are universal in that they apply to all
programming environments.
4 Contents
Manual Organization
This user’s guide is divided into eight chapters and six appendices:
“Chapter 1. Introduction,” describes the Cx51 compiler.
“Chapter 2. Compiling with Cx51,” explains how to compile a source file using
the Cx51 cross compiler. This chapter describes the command-line directives
that control file processing, compiling, and output.
“Chapter 7. Error Messages,” lists fatal errors, syntax errors, and warnings you
may encounter while using Cx51.
Document Conventions
This document uses the following conventions:
Examples Description
README.TXT Bold capitalized text is used for the names of executable programs, data files,
source files, environment variables, and commands you enter at the Windows
command prompt. This text usually represents commands that you must type
in literally.
Example:: CLS DIR BL51.EXE
Note that you are not required to enter these commands using all capital
letters.
Language Elements of the C language are presented in bold type. This includes
Elements keywords, operators and library functions.
Example: if != long
isdigit main >>
Courier Text in this typeface is used to represent information that displays on screen or
prints at the printer.
This typeface is also used within the text when discussing or describing
command line items.
Variables Text in italics represents information that you must provide. For example,
projectfile in a syntax string means that you are required to supply the actual
project filename.
Occasionally, italics are also used to emphasize words in the text.
Elements that Ellipses (…) are used in examples to indicate an item that may be repeated.
repeat…
Omitted code Vertical ellipses are used in source code examples to indicate a fragment of the
. program is omitted.
.
Example:
.
void main (void) {
.
.
.
while (1);
Optional Items Optional arguments in command-line and option fields are indicated by double
brackets.
Contents
Chapter 1. Introduction....................................................................................17
Support for all 8051 Variants...................................................................................... 17
Books About the C Language ..................................................................................... 18
Chapter 2. Compiling with Cx51.....................................................................19
Environment Variables ............................................................................................... 19
Running Cx51 from the Command Prompt................................................................. 20
ERRORLEVEL..................................................................................................... 21
Cx51 Output Files ................................................................................................. 21
Control Directives....................................................................................................... 22
Directive Categories.............................................................................................. 22
Reference .................................................................................................................... 25
AREGS / NOAREGS............................................................................................ 26
ASM / ENDASM .................................................................................................. 28
BROWSE.............................................................................................................. 30
CODE.................................................................................................................... 31
COMPACT ........................................................................................................... 32
COND / NOCOND ............................................................................................... 33
DEBUG................................................................................................................. 35
DEFINE ................................................................................................................ 36
DISABLE.............................................................................................................. 37
EJECT................................................................................................................... 39
FLOATFUZZY ..................................................................................................... 40
INCDIR................................................................................................................. 41
INTERVAL........................................................................................................... 42
INTPROMOTE / NOINTPROMOTE .................................................................. 43
INTVECTOR / NOINTVECTOR ........................................................................ 46
LARGE ................................................................................................................. 48
LISTINCLUDE..................................................................................................... 49
MAXARGS........................................................................................................... 50
MOD517 / NOMOD517 ....................................................................................... 51
MODA2 / NOMODA2 ......................................................................................... 53
MODDP2 / NOMODDP2..................................................................................... 54
MODP2 / NOMODP2........................................................................................... 55
NOAMAKE .......................................................................................................... 56
NOEXTEND......................................................................................................... 57
OBJECT / NOOBJECT ........................................................................................ 58
OBJECTEXTEND................................................................................................ 59
ONEREGBANK ................................................................................................... 60
OMF2.................................................................................................................... 61
OPTIMIZE............................................................................................................ 62
ORDER ................................................................................................................. 64
PAGELENGTH .................................................................................................... 65
PAGEWIDTH....................................................................................................... 66
8 Contents
PREPRINT............................................................................................................67
PRINT / NOPRINT...............................................................................................68
REGFILE ..............................................................................................................69
REGISTERBANK ................................................................................................70
REGPARMS / NOREGPARMS ...........................................................................71
RET_PSTK, RET_XSTK ....................................................................................73
ROM......................................................................................................................75
SAVE / RESTORE................................................................................................76
SMALL .................................................................................................................77
SRC .......................................................................................................................78
STRING ................................................................................................................79
SYMBOLS ............................................................................................................80
VARBANKING ....................................................................................................81
WARNINGLEVEL ...............................................................................................82
Chapter 3. Language Extensions .....................................................................85
Keywords ....................................................................................................................85
8051 Memory Areas....................................................................................................86
Program Memory ..................................................................................................86
Internal Data Memory ...........................................................................................87
External Data Memory ..........................................................................................88
Special Function Register Memory .......................................................................89
Memory Models..........................................................................................................89
Small Model ..........................................................................................................89
Compact Model .....................................................................................................90
Large Model ..........................................................................................................90
Memory Types ............................................................................................................90
Explicitly Declared Memory Types.......................................................................91
Implicit Memory Types .........................................................................................92
Data Types ..................................................................................................................92
Bit Types.....................................................................................................................93
Bit-addressable Objects...............................................................................................94
Special Function Registers ..........................................................................................96
sfr ..........................................................................................................................96
sfr16 ......................................................................................................................97
sbit.........................................................................................................................97
Absolute Variable Location ........................................................................................99
Pointers .....................................................................................................................101
Generic Pointers ..................................................................................................101
Memory-specific Pointers....................................................................................104
Pointer Conversions ............................................................................................106
Abstract Pointers .................................................................................................109
Function Declarations ...............................................................................................113
Function Parameters and the Stack......................................................................114
Passing Parameters in Registers ..........................................................................115
Function Return Values .......................................................................................115
Specifying the Memory Model for a Function.....................................................116
Specifying the Register Bank for a Function .......................................................117
Keil Software — Cx51 Compiler User’s Guide 9
gets ......................................................................................................................252
init_mempool.......................................................................................................253
_irol_ ...................................................................................................................254
_iror_...................................................................................................................255
isalnum ................................................................................................................256
isalpha .................................................................................................................257
iscntrl...................................................................................................................258
isdigit...................................................................................................................259
isgraph .................................................................................................................260
islower .................................................................................................................261
isprint...................................................................................................................262
ispunct .................................................................................................................263
isspace .................................................................................................................264
isupper .................................................................................................................265
isxdigit.................................................................................................................266
labs ......................................................................................................................267
log / log517 .........................................................................................................268
log10 / log10517 .................................................................................................269
longjmp ...............................................................................................................270
_lrol_ ...................................................................................................................272
_lror_...................................................................................................................273
malloc..................................................................................................................274
memccpy .............................................................................................................275
memchr................................................................................................................276
memcmp ..............................................................................................................277
memcpy ...............................................................................................................278
memmove ............................................................................................................279
memset ................................................................................................................280
modf ....................................................................................................................281
_nop_...................................................................................................................282
offsetof ................................................................................................................283
pow......................................................................................................................284
printf / printf517 ..................................................................................................285
putchar.................................................................................................................291
puts ......................................................................................................................292
rand......................................................................................................................293
realloc..................................................................................................................294
scanf ....................................................................................................................295
setjmp ..................................................................................................................299
sin / sin517 ..........................................................................................................300
sinh ......................................................................................................................301
sprintf / sprintf517 ...............................................................................................302
sqrt / sqrt517........................................................................................................304
srand ....................................................................................................................305
sscanf / sscanf517 ................................................................................................306
strcat ....................................................................................................................308
strchr....................................................................................................................309
Keil Software — Cx51 Compiler User’s Guide 13
strcmp.................................................................................................................. 310
strcpy................................................................................................................... 311
strcspn ................................................................................................................. 312
strlen.................................................................................................................... 313
strncat.................................................................................................................. 314
strncmp................................................................................................................ 315
strncpy................................................................................................................. 316
strpbrk ................................................................................................................. 317
strpos................................................................................................................... 318
strrchr .................................................................................................................. 319
strrpbrk................................................................................................................ 320
strrpos.................................................................................................................. 321
strspn................................................................................................................... 322
strtod / strtod517 ............................................................................................... 323
strtol .................................................................................................................... 325
strtoul .................................................................................................................. 327
tan / tan517.......................................................................................................... 329
tanh...................................................................................................................... 330
_testbit_............................................................................................................... 331
toascii .................................................................................................................. 332
toint ..................................................................................................................... 333
tolower ................................................................................................................ 334
_tolower .............................................................................................................. 335
toupper ................................................................................................................ 336
_toupper .............................................................................................................. 337
ungetchar............................................................................................................. 338
va_arg.................................................................................................................. 339
va_end ................................................................................................................. 341
va_start................................................................................................................ 342
vprintf.................................................................................................................. 343
vsprintf ................................................................................................................ 345
Appendix A. Differences from ANSI C.........................................................347
Compiler-related Differences.................................................................................... 347
Library-related Differences....................................................................................... 347
Appendix B. Version Differences...................................................................351
Version 6.0 Differences ............................................................................................ 351
Version 5 Differences ............................................................................................... 351
Version 4 Differences ............................................................................................... 352
Version 3.4 Differences ............................................................................................ 355
Version 3.2 Differences ............................................................................................ 356
Version 3.0 Differences ............................................................................................ 357
Version 2 Differences ............................................................................................... 358
Using C51 Version 5 with Previous Versions........................................................... 359
Appendix C. Writing Optimum Code ...........................................................361
Memory Model ......................................................................................................... 361
14 Contents
Variable Location......................................................................................................363
Variable Size.............................................................................................................363
Unsigned Types.........................................................................................................364
Local Variables .........................................................................................................364
Other Sources............................................................................................................364
Appendix D. Compiler Limits........................................................................365
Limitations of the Cx51 Compiler Implementation ...................................................365
Limitations of the Intel Object Module Format.........................................................366
Appendix E. Byte Ordering............................................................................367
Appendix F. Hints, Tips, and Techniques.....................................................369
Recursive Code Reference Error...............................................................................369
Problems Using the printf Routines ..........................................................................370
Uncalled Functions....................................................................................................371
Trouble with the bdata Memory Type.......................................................................372
Using Monitor-51......................................................................................................373
Function Pointers ......................................................................................................374
Glossary.............................................................................................................375
Index ..................................................................................................................382
Keil Software — Cx51 Compiler User’s Guide 15
Keil Software — Cx51 Compiler User’s Guide 17
Chapter 1. Introduction
The C programming language is a general-purpose, programming language that
provides code efficiency, elements of structured programming, and a rich set of 1
operators. C is not a big language and is not designed for any one particular area
of application. Its generality combined with its absence of restrictions, makes C
a convenient and effective programming solution for a wide variety of software
tasks. Many applications can be solved more easily and efficiently with C than
with other more specialized languages.
The C language on its own is not capable of performing operations (such as input
and output) that would normally require intervention from the operating system.
Instead, these capabilities are provided as part of the standard library. Because
these functions are separate from the language itself, C is especially suited for
producing code that is portable across a wide number of platforms.
For optimum support of these different 8051 variants, Keil provides the several
development tools that are listed in the table below. A new output file format
(OMF2) allows direct support of up to 16MB code and data space. The CX51
compiler is a variant of the C51 compiler that is design for the new Philips
80C51MX architecture.
18 Chapter 1. Introduction
1
A51 Macro Assembler Includes support for 32 x 64KB code banks.
BL51 Linker/Locater
C51 Compiler (with OMF2 Output) Development Tools for classic 8051 and extended
AX51 Macro Assembler 8051 variants (like Dallas 390). Includes support for
LX51 Linker/Locater code banking and up to 16MB code and xdata memory.
CX51 Compiler Development Tools for Philips 80C51MX
AX51 Macro Assembler Supports up to 16MB code and xdata memory.
LX51 Extended Linker/Locater
The Cx51 compiler is available in different packages. The table above
refers to the entire line of the 8051 development tools.
NOTE
The term Cx51 is used to refer to both compiler variants: the C51 compiler and
the CX51 compiler.
NOTE
Typically you will use the Cx51 compiler within the µVision2 IDE. For more
information on using the µVision2 IDE refer to the µVision2 Getting Started for
8051 User’s Guide.
Environment Variables
If you run the Cx51 compiler within the µVision2 IDE, you need no additional
settings on your computer. If you want to run the Cx51 compiler and utilities
from the command prompt, you must manually create the following environment
variables.
For Windows NT and Windows 2000 these environment variables are entered
under Control Panel – System – Advanced – Environment Variables.
For Windows 95, Windows 98 and Windows ME the settings are placed in
AUTOEXEC.BAT using the following commands:
PATH = C:\C51\BIN;%PATH%
SET TMP = D:\
SET C51INC = C:\C51\INC
SET C51LIB = C:\C51\LIB
20 Chapter 2. Compiling with Cx51
or:
C51 @commandfile
CX51 @commandfile
where:
sourcefile is the name of the source program you want to compile.
directives are the directives you want to use to control the function of the
compiler. Refer to “Control Directives” on page 22 for a
detailed list of the available directives.
commandfile is the name of a command input file that may contain sourcefile
and directives. A commandfile is used, when the Cx51
invocation line gets complex and exceeds the limits of the
Windows command prompt.
The following command line example invokes C51, specifies the source file
SAMPLE.C, and uses the controls DEBUG, CODE, and PREPRINT.
C51 SAMPLE.C DEBUG CODE PREPRINT
ERRORLEVEL
After compilation, the number of errors and warnings detected is output to the
screen. Cx51 then sets the ERRORLEVEL to indicate the status of the
compilation. Values are listed in the following table:
ERRORLEVEL Meaning
0
1
No errors or warnings
Warnings only
2
2 Errors and possibly warnings
3 Fatal errors
You can access the ERRORLEVEL variable in batch files. Refer to the Windows
command index or to batch commands in the Windows on-line help for more
information on ERRORLEVEL or batch files.
Control Directives
Cx51 offers a number of control directives that you can use to control the
operation of the compiler. Directives are composed of one or more letters or
digits and, unless otherwise specified, can be specified after the filename on the
command line or within a source file using the #pragma directive.
2 Example
C51 testfile.c SYMBOLS CODE DEBUG
In the above examples, SYMBOLS, CODE, and DEBUG are all control directives.
testfile.c is the source file to be compiled.
NOTE
The syntax is the same for the command line and the #pragma directive.
Multiple options, however, may be specified on the #pragma line.
Typically, each control directive may be specified only once at the beginning of
a source file. If a directive is specified more than once, the compiler generates a
fatal error and aborts compilation. Directives that may be specified more than
once are so noted in the following sections.
Directive Categories
Control directives can be divided into three groups: source controls, object
controls, and listing controls.
Source controls define macros on the command line and determine the name
of the file to be compiled.
Object controls affect the form and content of the generated object module
(*.OBJ). These directives allow you to specify the optimizing level or
include debugging information in the object file.
Listing controls govern various aspects of the listing file (*.LST), in
particular its format and specific content.
Keil Software — Cx51 Compiler User’s Guide 23
2 REGFILE †
REGISTERBANK
Object
Object
Specify a register definition file for global register optimization.
Select the register bank that is used for absolute register
accesses.
REGPARMS, Object Enable or disable register parameter passing.
NOREGPARMS
RET_PSTK †, Object Use reentrant stack for saving return addresses.
RET_XSTK †
ROM † Object Control generation of AJMP/ACALL instructions.
SAVE, Object Saves and restores settings for AREGS, REGPARMS and
RESTORE OPTIMIZE directives.
SMALL † Object Select SMALL memory model. (Default.)
SRC † Object Create an assembler source file instead of an object module.
STRING † Object Locate implicit string constants to xdata or far memory.
SYMBOLS † Listing Include a list of all symbols used within the module in the listing
file.
VARBANKING † Object Use library set for variable banking support.
WARNINGLEVEL † Listing Selects the level of Warning detection.
† These directives may be specified only once on the command line or at the beginning of a source
file using in the #pragma statement. They may not be used more than once in a source file.
Reference
The remainder of this chapter is devoted to describing each of the available
Cx51 compiler control directives. The directives are listed in alphabetical order,
and each is divided into the following sections:
µVision2 Control: Gives the dialog box in the µVision2 IDE which allows you
to specify the directive.
AREGS / NOAREGS
Abbreviation: None.
Arguments: None.
Default: AREGS
NOTE
Though it may be defined several times in a program, the
AREGS / NOAREGS option is valid only when defined
outside of a function declaration.
Keil Software — Cx51 Compiler User’s Guide 27
Example: The following is a source and code listing which uses both
NOAREGS and AREGS.
stmt level source
1 extern char func ();
2 char k;
3
4 #pragma NOAREGS
5 noaregfunc () {
6 1 k = func () + func ();
7
8
9
1 }
#pragma AREGS
2
10 aregfunc () {
11 1 k = func () + func ();
12 1 }
ASM / ENDASM
Abbreviation: None.
Arguments: None.
Default: None.
NOTE
The ASM / ENDASM directive can occur only in the source
file, as part of a #pragma directive.
Keil Software — Cx51 Compiler User’s Guide 29
2
2
3 main () {
4 1 test ();
5 1
6 1 #pragma asm
7 1 JMP $ ; endless loop
8 1 #pragma endasm
9 1 }
.
.
.
BROWSE
Abbreviation: BR
Arguments: None.
#pragma browse
Keil Software — Cx51 Compiler User’s Guide 31
CODE
Abbreviation: CD
Arguments: None.
#pragma code
COMPACT
Abbreviation: CP
Arguments: None.
Default: SMALL
NOTE
The stack required for function calls is always placed in
IDATA memory.
#pragma compact
Keil Software — Cx51 Compiler User’s Guide 33
COND / NOCOND
Abbreviation: CO
Arguments: None.
Default: COND
Example: The following example shows the listing file for a source
file compiled with the COND directive.
.
.
.
stmt level source
1 extern unsigned char a, b;
2 unsigned char c;
3
2 4
5
6 1
main()
{
#if defined (VAX)
c = 13;
#elif defined (_ _TIME_ _)
9 1 b = 14;
10 1 a = 15;
11 1 #endif
12 1 }
.
.
.
DEBUG
Abbreviation: DB
Arguments: None.
NOTE
The OBJECTEXTEND directive can be used to instruct the
compiler to include additional variable type definition
information in the object file.
#pragma db
36 Chapter 2. Compiling with Cx51
DEFINE
Abbreviation: DF
NOTE
The DEFINE directive can be specified only on the
command line. Use the C preprocessor #define directive for
use inside a C source.
DISABLE
Abbreviation: None.
Arguments: None.
Default: None.
NOTE
DISABLE may be specified using the #pragma directive
only, and may not be specified at the command line.
2
.
stmt level source
1 typedef unsigned char uchar;
2
3 #pragma disable /* Disable Interrupts */
4 uchar dfunc (uchar p1, uchar p2) {
5 1 return (p1 * p2 + p2 * p1);
6 1 }
EJECT
Abbreviation: EJ
Arguments: None.
Default: None.
NOTE
The EJECT directive occurs only in the source file, and
must be part of a #pragma directive.
FLOATFUZZY
Abbreviation: FF
#pragma FF (0)
Keil Software — Cx51 Compiler User’s Guide 41
INCDIR
Abbreviation: ID
Default: None.
INTERVAL
Abbreviation: None
(interval × n) + offset + 3,
where:
interval is the argument of the INTERVAL
directive (default 8).
n is the interrupt number.
offset is the argument of the INTVECTOR
directive (default 0).
#pragma interval(3)
Keil Software — Cx51 Compiler User’s Guide 43
INTPROMOTE / NOINTPROMOTE
Abbreviation: IP / NOIP
Arguments: None.
Default: INTPROMOTE
#pragma intpromote
1 char c;
2 unsigned char c1,c2;
3 int i;
2 4
5
6
7
1
1
main () {
if (c == 0xff) c = 0;
if (c == -1) c = 1;
/* never true! */
/* works */
8 1 i = c + 5;
9 1 if (c1 < c2 +4) c1 = 0;
10 1 }
Keil Software — Cx51 Compiler User’s Guide 45
INTVECTOR / NOINTVECTOR
Abbreviation: IV / NOIV
(interval × n) + offset + 3,
where:
n is the interrupt number.
interval is the argument of the INTERVAL
directive (default 8).
offset is the argument of the INTVECTOR
directive (default 0).
See Also: INTERVAL
Keil Software — Cx51 Compiler User’s Guide 47
#pragma iv(0x8000)
#pragma noiv
2
48 Chapter 2. Compiling with Cx51
LARGE
Abbreviation: LA
Arguments: None.
Default: SMALL
NOTE
The stack required for function calls is always placed in
IDATA memory.
#pragma large
Keil Software — Cx51 Compiler User’s Guide 49
LISTINCLUDE
Abbreviation: LC
Arguments: None.
Default: NOLISTINCLUDE
#pragma listinclude
50 Chapter 2. Compiling with Cx51
MAXARGS
Abbreviation: None.
Description: With the MAXARGS directive, you specify the buffer size
for parameters passed in variable-length argument lists.
MAXARGS defines the maximum number of parameters.
The MAXARGS directive must be applied before the C
function. This directive has no impact on the maximum
number of arguments that may be passed to reentrant
functions.
#include <stdarg.h>
MOD517 / NOMOD517
Abbreviation: None.
Default: NOMOD517
Directive Description
NOAU When specified, C51 uses only the additional data
pointers of the Infineon device. The arithmetic processor
is not used. The NOAU parameter is useful for functions
that are called by an interrupt while the arithmetic
processor is already being used.
52 Chapter 2. Compiling with Cx51
Directive Description
NODP8 When specified, C51 uses only the arithmetic processor.
The additional data pointers are not used. The NODP8
parameter is useful for interrupt functions declared without
the using function attribute. In this case, the extra data
pointers are not used and, therefore, do not need to be
saved on the stack during the interrupt.
NOTE
Though it may be defined several times in a program, the
MOD517 directive is valid only when defined outside of a
function declaration.
#pragma NOMOD517
Keil Software — Cx51 Compiler User’s Guide 53
MODA2 / NOMODA2
Abbreviation: None.
Arguments: MODA2
Default: NOMODA2
#pragma moda2
#pragma nomoda2
54 Chapter 2. Compiling with Cx51
MODDP2 / NOMODDP2
Abbreviation: None.
Arguments: MODDP2
Default: NOMODDP2
#pragma moddp2
#pragma nomoddp2
Keil Software — Cx51 Compiler User’s Guide 55
MODP2 / NOMODP2
Abbreviation: None.
Arguments: MODP2
Default: NOMODP2
#pragma modp2
#pragma nomodp2
56 Chapter 2. Compiling with Cx51
NOAMAKE
Abbreviation: NOAM
Arguments: None.
#pragma NOAM
Keil Software — Cx51 Compiler User’s Guide 57
NOEXTEND
Abbreviation: None.
Arguments: None.
#pragma NOEXTEND
58 Chapter 2. Compiling with Cx51
OBJECT / NOOBJECT
Abbreviation: OJ / NOOJ
#pragma oj(sample_1.obj)
#pragma nooj
Keil Software — Cx51 Compiler User’s Guide 59
OBJECTEXTEND
Abbreviation: OE
Arguments: None.
Default: None.
NOTE
Object files generated using this directive contain a superset
of the OMF-51 specification for relocatable object formats.
Emulators or simulators must provide enhanced object
loaders to use this feature. If in doubt, do not use
OBJECTEXTEND.
#pragma oe db
60 Chapter 2. Compiling with Cx51
ONEREGBANK
Abbreviation: OB
Arguments: None
Default: None
#pragma OB
Keil Software — Cx51 Compiler User’s Guide 61
OMF2
Abbreviation: O2
Arguments: None
Default: The C51 compiler generates by default the Intel OMF51 file
format. The OMF2 file format is default for the CX51
compiler. 2
µVision2 Control: Project – Select Device – Use LX51 instead of BL51.
Description: The OMF2 directive enables the OMF2 file format. The
OMF2 file format provides detailed symbol type checking
across moduls and eliminates historic limitations of the Intel
OMF51 file format. Constants can be located also into an
xdata ROM to free code space for program code. The
OMF2 file format is required when you want to use one of
the following features of the C51 compiler:
VARBANKING directive for using the far memory type.
const xdata memory type to use a ROM in xdata space.
STRING directive to locate string constants into xdata or
far space.
ROM (D512K) or ROM (D16M) for using the
contigouos CPU mode on Dallas 390 and variants.
The OMF2 file format requires the extended LX51
linker/locater and cannot be used with the BL51
linker/locater.
#pragma O2
62 Chapter 2. Compiling with Cx51
OPTIMIZE
Abbreviation: OT
NOTE
Each higher optimization level contains all of the
characteristics of the preceding lower optimization level.
Level Description
0 Constant Folding: The compiler performs calculations that
reduce expressions to numeric constants, where possible.
This includes calculations of run-time addresses.
Level Description
4 Register Variables: Automatic variables and function
arguments are located in registers when possible.
Reservation of data memory for these variables is omitted.
#pragma ot(size)
64 Chapter 2. Compiling with Cx51
ORDER
Abbreviation: OR
Arguments: None.
#pragma OR
Keil Software — Cx51 Compiler User’s Guide 65
PAGELENGTH
Abbreviation: PL
#pragma pl (70)
66 Chapter 2. Compiling with Cx51
PAGEWIDTH
Abbreviation: PW
#pragma pw(79)
Keil Software — Cx51 Compiler User’s Guide 67
PREPRINT
Abbreviation: PP
NOTE
The PREPRINT directive may be specified only on the
command line. It may not be specified in the C source file
by means of the #pragma directive.
PRINT / NOPRINT
Abbreviation: PR / NOPR
#pragma pr (\usr\list\sample.lst)
#pragma nopr
Keil Software — Cx51 Compiler User’s Guide 69
REGFILE
Abbreviation: RF
Default: None.
#pragma REGFILE(sample.reg)
70 Chapter 2. Compiling with Cx51
REGISTERBANK
Abbreviation: RB
NOTE
Unlike the using function attribute, the REGISTERBANK
control does not switch the register bank.
#pragma rb(3)
Keil Software — Cx51 Compiler User’s Guide 71
REGPARMS / NOREGPARMS
Abbreviation: None.
Arguments: None.
Default: REGPARMS
NOTE
You may specify both the REGPARMS and
NOREGPARMS directives several times within a source
program. This allows you to create some program sections
with register parameters and other sections using the old
style of parameter passing. Use NOREGPARMS to access
existing older assembler functions or library files without
having to reassemble or recompile them. This is illustrated
in the following example program.
main () {
char a;
int x1, x2;
x1 = old_func (x2, a);
x1 = new_func (x2, a);
}
72 Chapter 2. Compiling with Cx51
2
Keil Software — Cx51 Compiler User’s Guide 73
RET_PSTK, RET_XSTK
Abbreviation: RP, RX
Arguments: None.
Default: None.
NOTES
You may use the RET_xSTK directives to unload return
addresses from the on-chip or hardware stack. These
directives may be selectively used on the modules that
contain the deepest stack nesting.
If you use one of these directives you must initilize the
reentrant stack pointer defined in the startup code. Refer to
“STARTUP.A51” on page 144 for more information on how
to initilize the reentrant stacks.
1 #pragma RET_XSTK
2 extern void func2 (void);
3
4 void func (void) {
5 1 func2 ();
6 1 }
2
Keil Software — Cx51 Compiler User’s Guide 75
ROM
Abbreviation: None.
Option Description
SMALL CALL and JMP instructions are coded as ACALL and
AJMP. The maximum program size may be 2 KBytes. The
entire program must be allocated within the 2 KByte
program memory space.
COMPACT CALL instructions are coded as LCALL. JMP instructions
are coded as AJMP within a function. The size of a
function must not exceed 2 KBytes. The entire program
may, however, comprise a maximum of 64 KBytes. The
type of application determines whether or not
ROM (COMPACT) is more advantageous than
ROM (LARGE). Any code space saving advantages in
using ROM (COMPACT) must be empirically determined.
LARGE CALL and JMP instructions are coded as LCALL and
LJMP. This allows you to use the entire address space
without any restrictions. Program size is limited to
64 KBytes. Function size is also limited to 64 KBytes.
D512K C51 generates ACALL and AJMP instructions with 19-bit
(Dallas 390 address for using the contiguous mode of Dallas 390 and
& variants) variants. The maximum program size may be 512 KBytes.
D16M C51 generates LCALL with 24-bit address and AJMP
(Dallas 390 instructions with 19-bit address for using the contiguous
& variants) mode of Dallas 390 and variants. The maximum program
size may be 16MBytes.
The option D512K and D16M require the OMF251 directive.
SAVE / RESTORE
Abbreviation: None.
Arguments: None.
Default: None.
NOTE
SAVE and RESTORE may be specified only as an argument
of a #pragma statement. You may not specify this control
option in the command line.
#pragma restore
SMALL
Abbreviation: SM
Arguments: None.
Default: SMALL
NOTE
The stack required for function calls is always placed in
IDATA memory.
#pragma small
78 Chapter 2. Compiling with Cx51
SRC
Abbreviation: None.
Default: None.
NOTE
The compiler cannot simultaneously produce a source file
and an object file.
STRING
Abbreviation: ST
Option Description
CODE Implicit strings are located in code space. This is the
default setting of the Cx51 compiler.
XDATA Implicit strings are located in const xdata space.
FAR Implicit strings are located in const far space.
The option XDATA and FAR require the OMF2 directive.
SYMBOLS
Abbreviation: SB
Arguments: None.
#pragma SYMBOLS
VARBANKING
Abbreviation: VB
Arguments: None.
NOTE
For extended 8051 devices and variable banking with
classic 8051 devices several Keil Application Notes will
become available on www.keil.com or the Keil development
tools CD-ROM that explain the banking and memory
configuration for these devices.
#pragma VARBANKING
82 Chapter 2. Compiling with Cx51
WARNINGLEVEL
Abbreviation: WL
2
Keil Software — Cx51 Compiler User’s Guide 85
Bit variables and bit-addressable data
Special Function Registers
3
Pointers
Function Attributes
Keywords
To facilitate many of the features of the 8051, Cx51 adds a number of new
keywords to the scope of the C language. The following is a list of the keywords
available in Cx51:
You can disable these extensions using the NOEXTEND control directive.
Refer to “Chapter 2. Compiling with Cx51” on page 19 for more information.
86 Chapter 3. Language Extensions
Program memory can be accessed by using the code memory type specifier in
Cx51.
Keil Software — Cx51 Compiler User’s Guide 87
Access to internal data memory is very fast because it can be accessed using an
8-bit address. However, internal data memory is limited to a maximum of 256
bytes.
Internal data can be broken down into three distinct data types when using Cx51:
data, idata, and bdata.
3
The data memory specifier always refers to the first 128 bytes of internal data
memory. Variables stored here are accessed using direct addressing.
The idata memory specifier refers to all 256 bytes of internal data memory;
however, this memory type specifier code is generated by indirect addressing
which is slower than direct addressing.
There are two different data types in Cx51 with which you may access external
data: xdata and pdata.
The xdata memory specifier refers to any location in the 64 KByte address space
of external data memory.
The pdata memory type specifier refers to only 1 page or 256 bytes of external
data memory. See “Compact Model” on page 90 for more information on pdata.
Keil Software — Cx51 Compiler User’s Guide 89
Memory Models
The memory model determines which default memory type to use for function
arguments, automatic variables, and declarations with no explicit memory type
specifier. You specify the memory model on the Cx51 command line using the
SMALL, COMPACT and LARGE control directives. Refer to “Control
3
Directives” on page 22 for more information about these directives.
NOTE
Except in very special selected applications, always use the default SMALL
memory model. It generates the fastest, most efficient code.
Small Model
In this model, all variables, by default, reside in the internal data memory of the
8051 system. (This is the same as if they were declared explicitly using the data
memory type specifier.) In this memory model, variable access is very efficient.
However, all objects, as well as the stack must fit into the internal RAM. Stack
size is critical because the real stack size depends upon the nesting depth of the
various functions. Typically, if the linker/locator is configured to overlay
variables in the internal data memory, the small model is the best model to use.
90 Chapter 3. Language Extensions
Compact Model
Using the compact model, all variables, by default, reside in one page of external
data memory. (This is as if they were explicitly declared using the pdata
memory type specifier.) This memory model can accommodate a maximum of
256 bytes of variables. The limitation is due to the addressing scheme used,
which is indirect through registers R0 and R1 (@R0, @R1). This memory
model is not as efficient as the small model, therefore, variable access is not as
fast. However, the compact model is faster than the large model.
When using the compact model, Cx51 accesses external memory with
instructions that utilize the @R0 and @R1 operands. R0 and R1 are byte
3 registers and provide only the low-order byte of the address. If the compact
model is used with more than 256 bytes of external memory, the high-order
address byte (or page) is provided by Port 2 on the 8051. In this case, you must
initialize Port 2 with the proper external memory page to use. This can be done
in the startup code. You must also specify the starting address for PDATA to
the linker. Refer to “STARTUP.A51” on page 144 for more information on
using the compact model.
Large Model
In the large model, all variables, by default, reside in external data memory (up
to 64 KBytes). (This is the same as if they were explicitly declared using the
xdata memory type specifier.) The data pointer (DPTR) is used for addressing.
Memory access through this data pointer is inefficient, especially on variables
with a length of two or more bytes. This type of data access mechanism
generates more code than the small or compact models.
Memory Types
The Cx51 compiler explicitly supports the architecture of the 8051 and its
derivatives and provides access to all memory areas of the 8051. Each variable
may be explicitly assigned to a specific memory space.
Accessing the internal data memory is considerably faster than accessing the
external data memory. For this reason, place frequently used variables in
internal data memory. Place larger, less frequently used variables in external
data memory.
Keil Software — Cx51 Compiler User’s Guide 91
bdata
address space (256 bytes).
Bit-addressable internal data memory; allows mixed bit and byte access
(16 bytes).
3
xdata External data memory (64 KBytes); accessed by opcode MOVX @DPTR.
pdata Paged (256 bytes) external data memory; accessed by opcode MOVX @Rn.
As with the signed and unsigned attributes, you may include memory type
specifiers in the variable declaration.
Example:
char data var1;
char code text[] = "ENTER PARAMETER:";
unsigned long xdata array[100];
float idata x,y,z;
unsigned int pdata dimension;
unsigned char xdata vector[10][4][4];
char bdata flags;
NOTE
For compatibility with previous versions of the Cx51 compiler, you may specify
the memory area before the data type. For example, the following declaration
data char x;
is equivalent to
char data x;
Nonetheless, this feature should not be used in new programs because it may not
be supported in future versions of the Cx51 compiler.
92 Chapter 3. Language Extensions
3 Data Types
Cx51 provides you with a number of basic data types to use in your C programs.
Cx51 offers you the standard C data types and also supports several data types
that are unique to the 8051 platform. The following table lists the available
Cx51 data types.
Bit Types
Cx51 provides you with a bit data type that may be used for variable
declarations, argument lists, and function return values. A bit variable is
declared the same as other C data types.
Example:
static bit done_flag = 0; /* bit variable */
3
.
.
.
return (0); /* bit return value */
}
All bit variables are stored in a bit segment located in the internal memory area
of the 8051. Because this area is only 16 bytes long, a maximum of 128 bit
variables may be declared within any one scope.
Bit-addressable Objects
Bit-addressable objects are objects which can be addressed as bytes or as bits.
Only data objects that occupy the bit-addressable area of the 8051 internal
memory fall into this category. The Cx51 compiler places variables declared
with the bdata memory type into this bit-addressable area. You may declare
these variables as shown below:
int bdata ibase; /* Bit-addressable int */
The variables ibase and bary are bit-addressable. Therefore, the individual
3 bits of these variables may be directly accessed and modified. Use the sbit
keyword to declare new variables that access the bits of variables declared using
bdata. For example:
sbit mybit0 = ibase ^ 0; /* bit 0 of ibase */
sbit mybit15 = ibase ^ 15; /* bit 15 of ibase */
The above example represents declarations, not assignments to the bits of the
ibase and bary variables declared above. The expression following the carat
symbol (‘^’) in the example, specifies the position of the bit to access with this
declaration. This expression must be a constant value. The range depends on
the type of the base variable included in the declaration. The range is 0 to 7 for
char and unsigned char, 0 to 15 for int, unsigned int, short, and unsigned
short, and 0 to 31 for long and unsigned long.
You may provide external variable declarations for the sbit type to access these
types in other modules. For example:
extern bit mybit0; /* bit 0 of ibase */
extern bit mybit15; /* bit 15 of ibase */
Declarations involving the sbit type require that the base object be declared with
the memory type bdata. The only exceptions are the variants for special
function bits. Refer to “Special Function Registers” on page 96 for more
information.
Keil Software — Cx51 Compiler User’s Guide 95
The following example shows how to change the ibase and bary bits using the
above declarations.
Ary37 = 0; /* clear bit 7 in bary[3] */
bary[3] = 'a'; /* Byte addressing */
ibase = -1; /* Word addressing */
mybit15 = 1; /* set bit 15 in ibase */
The bdata memory type is handled like the data memory type except that
variables declared with bdata reside in the bit-addressable portion of the
internal data memory. Note that the total size of this area of memory may not
exceed 16 bytes.
In addition to declaring sbit variables for scalar types, you may also declare sbit
variables for structures and unions. For example:
union lft
3
{
float mf;
long ml;
};
NOTE
You may not specify bit variables for the bit positions of a float. However, you
may include the float and a long in a union. Then, you may declare bit
variables to access the bits in the long type.
The sbit data type uses the specified variable as a base address and adds the bit
position to obtain a physical bit address. Physical bit addresses are not
equivalent to logical bit positions for certain data types. Physical bit position 0
refers to bit position 0 of the first byte. Physical bit position 8 refers to bit
position 0 of the second byte. Because int variables are stored high-byte first,
bit 0 of the integer is located in bit position 0 of the second byte. This is physical
bit position 8 when accessed using an sbit data type.
96 Chapter 3. Language Extensions
Within the 8051 family, the number and type of SFRs vary. Note that no SFR
names are predefined by the Cx51 compiler. However, declarations for SFRs
are provided in include files.
3 Cx51 provides you with a number of include files for various 8051 derivatives.
Each file contains declarations for the SFRs available on that derivative. See
“8051 Special Function Register Include Files” on page 221 for more
information about include files.
Cx51 provides access to SFRs with the sfr, sfr16, and sbit data types. The
following sections describe each of these data types.
sfr
SFRs are declared in the same fashion as other C variables. The only difference
is that the data type specified is sfr rather than char or int. For example:
sfr P0 = 0x80; /* Port-0, address 80h */
sfr P1 = 0x90; /* Port-1, address 90h */
sfr P2 = 0xA0; /* Port-2, address 0A0h */
sfr P3 = 0xB0; /* Port-3, address 0B0h */
P0, P1, P2, and P3 are the SFR name declarations. Names for sfr variables are
defined just like other C variable declarations. Any symbolic name may be used
in an sfr declaration.
The address specification after the equal sign (=) must be a numeric constant.
(Expressions with operators are not allowed.) This constant expression must lie
in the SFR address range (0x80 to 0xFF).
Keil Software — Cx51 Compiler User’s Guide 97
sfr16
Many of the newer 8051 derivatives use two SFRs with consecutive addresses to
specify 16-bit values. For example, the 8052 uses addresses 0xCC and 0xCD for
the low and high bytes of timer/counter 2. Cx51 provides the sfr16 data type to
access 2 SFRs as a 16-bit SFR.
Access to 16-bit SFRs is possible only when the low byte immediately precedes
the high byte. The low byte is used as the address in the sfr16 declaration. For
example:
sfr16 T2 = 0xCC; /* Timer 2: T2L 0CCh, T2H 0CDh */
sfr16 RCAP2 = 0xCA; /* RCAP2L 0CAh, RCAP2H 0CBh */
In this example, T2 and RCAP2 are declared as 16-bit special function registers. 3
The sfr16 declarations follow the same rules as outlined for sfr declarations.
Any symbolic name can be used in an sfr16 declaration. The address
specification after the equal sign (‘=’) must be a numeric constant. Expressions
with operators are not allowed. The address must be the low byte of the SFR
low-byte, high-byte pair.
sbit
With typical 8051 applications, it is often necessary to access individual bits
within an SFR. The Cx51 compiler makes this possible with the sbit data type.
The sbit data type allows you to access bit-addressable SFRs. For example:
sbit EA = 0xAF;
This declaration defines EA to be the SFR bit at address 0xAF. On the 8051,
this is the enable all bit in the interrupt enable register.
NOTE
Not all SFRs are bit-addressable. Only those SFRs whose address is evenly
divisible by 8 are bit-addressable. The lower nibble of the SFR’s address must
be 0 or 8. For example, SFRs at 0xA8 and 0xD0 are bit-addressable, whereas
SFRs at 0xC7 and 0xEB are not. To calculate an SFR bit address, add the bit
position to the SFR byte address. So, to access bit 6 in the SFR at 0xC8, the SFR
bit address would be 0xCE (0xC8 + 6).
98 Chapter 3. Language Extensions
Any symbolic name can be used in an sbit declaration. The expression to the
right of the equal sign (=) specifies an absolute bit address for the symbolic
name. There are three variants for specifying the address:
3 sfr
sbit
sbit
IE = 0xA8;
OV = PSW ^ 2;
CY = PSW ^ 7;
sbit EA = IE ^ 7;
Variant 3: int_constant
This variant uses an absolute bit address for the sbit. For
example:
sbit OV = 0xD2;
sbit CY = 0xD7;
sbit EA = 0xAF;
NOTE
Special function bits represent an independent declaration class that may not be
interchangeable with other bit declarations or bit fields.
The sbit data type declaration may be used to access individual bits of variables
declared with the bdata memory type specifier. Refer to “Bit-addressable
Objects” on page 94 for more information.
Keil Software — Cx51 Compiler User’s Guide 99
where:
memory_space is the memory space for the variable. If missing from the
declaration, the default memory space is used. Refer to
“Memory Models” on page 89 for more information about
type
the default memory space.
is the variable type.
3
variable_name is the variable name.
constant is the address at which to locate the variable.
The absolute address following _at_ must conform to the physical boundaries of
the memory space for the variable. Cx51 checks for invalid address
specifications.
3 }
Often, you may wish to declare your variables in one source module and access
them in another. Use the following external declarations to access the _at_
variables defined above in another source file.
struct link
{
struct link idata *next;
char code *test;
};
Pointers
Cx51 supports the declaration of variable pointers using the * character. Cx51
pointers can be used to perform all operations available in standard C. However,
because of the unique architecture of the 8051 and its derivatives, Cx51 provides
two different types of pointers: memory-specific pointers and generic pointers.
Each of these pointer types, as well as conversion methods are discussed in the
following sections.
Generic Pointers
Generic pointers are declared in the same fashion as standard C pointers. For
example:
3
char *s; /* string ptr */
int *numptr; /* int ptr */
long *state; /* Texas */
Generic pointers are always stored using three bytes. The first byte is the
memory type, the second is the high-order byte of the offset, and the third is the
low-order byte of the offset. Generic pointers may be used to access any variable
regardless of its location in 8051 memory space. Many of the Cx51 library
routines use these pointer types for this reason. By using these generic pointers,
a function can access data regardless of the memory in which it is stored.
NOTE
The code generated for a generic pointer executes more slowly than the
equivalent code generated for a memory-specific pointer. This is because the
memory area is not known until run-time. The compiler cannot optimize memory
accesses and must generate generic code that can access any memory area. If
execution speed is a priority, you should use memory-specific pointers instead of
generic pointers wherever possible.
The following code and assembly listing shows the values assigned to generic
pointers for variables in different memory areas. Note that the first value is the
memory space followed by the high-order byte and low-order byte of the
address.
stmt level source
1 char *c_ptr; /* char ptr */
2 int *i_ptr; /* int ptr */
3 long *l_ptr; /* long ptr */
102 Chapter 3. Language Extensions
4
5 void main (void)
6 {
7 1 char data dj; /* data vars */
8 1 int data dk;
9 1 long data dl;
10 1
11 1 char xdata xj; /* xdata vars */
12 1 int xdata xk;
13 1 long xdata xl;
14 1
15 1 char code cj = 9; /* code vars */
16 1 int code ck = 357;
17 1 long code cl = 123456789;
18 1
19 1
20 1 c_ptr = &dj; /* data ptrs */
21 1 i_ptr = &dk;
3 22
23
24
1
1
1
l_ptr = &dl;
In the above example listing, the generic pointers c_ptr, i_ptr, and l_ptr
are all stored in the internal data memory of the 8051. However, you may
specify the memory area in which a generic pointer is stored by using a memory
type specifier. For example: 3
char * xdata strptr; /* generic ptr stored in xdata */
int * data numptr; /* generic ptr stored in data */
long * idata varptr; /* generic ptr stored in idata */
These examples are pointers to variables that may be stored in any memory area.
The pointers, however, are stored in xdata, data, and idata respectively.
104 Chapter 3. Language Extensions
Memory-specific Pointers
Memory-specific pointers always include a memory type specification in the
pointer declaration and always refer to a specific memory area. For example:
char data *str; /* ptr to string in data */
int xdata *numtab; /* ptr to int(s) in xdata */
long code *powtab; /* ptr to long(s) in code */
Because the memory type is specified at compile-time, the memory type byte
required by generic pointers is not needed by memory-specific pointers.
Memory-specific pointers can be stored using only one byte (idata, data, bdata,
and pdata pointers) or two bytes (code and xdata pointers).
3 NOTE
The code generated for a memory-specific pointer executes more quickly than
the equivalent code generated for a generic pointer. This is because the memory
area is known at compile-time rather than at run-time. The compiler can use
this information to optimize memory accesses. If execution speed is a priority,
you should use memory-specific pointers instead of generic pointers wherever
possible.
Like generic pointers, you may specify the memory area in which a
memory-specific pointer is stored. To do so, prefix the pointer declaration with
a memory type specifier. For example:
char data * xdata str; /* ptr in xdata to data char */
int xdata * data numtab; /* ptr in data to xdata int */
long code * idata powtab; /* ptr in idata to code long */
The following code and assembly listing shows how pointer values are assigned
to memory-specific pointers. Note that the code generated for these pointers is
much less involved than the code generated in the generic pointers example
listing in the previous section.
stmt level source
Pointer Conversions
Cx51 can convert between memory-specific pointers and generic pointers.
Pointer conversions can be forced by explicit program code using type casts or
can be coerced by the compiler.
In the call to printf, the argument fmt which represents a 2-byte code pointer is
automatically converted or coerced into a 3-byte generic pointer. This is done
because the prototype for printf requires a generic pointer as the first argument.
NOTE
A memory-specific pointer used as an argument to a function is always
converted into a generic pointer if no function prototype is present. This can
cause errors if the called function actually expects a shorter pointer as an
argument. In order to avoid these kinds of errors in programs, use #include
files, and prototype all external functions. This guarantees conversion of the
necessary types by the compiler and increases the likelihood that the compiler
detects type conversion errors.
Keil Software — Cx51 Compiler User’s Guide 107
The following table details the process involved in converting generic pointers
(generic *) to memory-specific pointers (code *, xdata *, idata *, data *,
pdata *).
The following listing illustrates a few pointer conversions and the resulting code:
stmt level source
1 int *p1; /* generic ptr (3 bytes) */
2 int xdata *p2; /* xdata ptr (2 bytes) */
3 int idata *p3; /* idata ptr (1 byte) */
4 int code *p4; /* code ptr (2 bytes */
5
6 void pconvert (void) {
7 1 p1 = p2; /* xdata* to generic* */
8 1 p1 = p3; /* idata* to generic* */
9 1 p1 = p4; /* code* to generic* */
10 1
11 1 p4 = p1; /* generic* to code* */
12 1 p3 = p1; /* generic* to idata* */
13 1 p2 = p1; /* generic* to xdata* */
14 1
3 15
16
1
*** WARNING
1
*** WARNING
p2 = p3;
p3 = p4;
/* idata* to
259 IN LINE 15 OF P.C: pointer:
/* code* to
259 IN LINE 16 OF P.C: pointer:
xdata* (WARN) */
different mspace
idata* (WARN) */
different mspace
17 1 }
Abstract Pointers
Abstract pointer types let you access fixed memory locations in any memory
area. You may also use abstract pointers to call functions located at absolute or
fixed addresses.
Abstract pointer types are described here through code examples which use the
following variables.
char xdata *px; /* ptr to xdata */
char idata *pi; /* ptr to idata */
char code *pc; /* ptr to code */
3 Source
Object
c = *((char code *) 0x8000);
0000 908000 MOV DPTR,#08000H
0003 E4 CLR A
0004 93 MOVC A,@A+DPTR
0005 F500 R MOV c,A
Like the previous example, this example casts 0x4000 as a pointer to a pointer in
xdata that points to a char in xdata. However, the pointer is accessed as an
array of pointers in xdata. The assignment accesses array element 0 (which is
stored at 0x4000 in xdata) and extracts the pointer there that points to the char
stored in xdata.
Source px = ((char xdata * xdata *) 0x4000) [0];
Object 0000 904000 MOV DPTR,#04000H
0003 E0 MOVX A,@DPTR
0004 FE MOV R6,A
0005 A3 INC DPTR
0006 E0 MOVX A,@DPTR
0007 8E00 R MOV px,R6
0009 F500 R MOV px+01H,A
3 The following example is identical to the previous one except that the
assignment accesses element 1 from the array. Since the object pointed to is a
pointer in xdata (to a char), the size of each element in the array is 2 bytes. The
assignment accesses array element 1 (which is stored at 0x4002 in xdata) and
extracts the pointer there that points to the char stored in xdata.
Source px = ((char xdata * xdata *) 0x4000) [1];
Object 0000 904002 MOV DPTR,#04002H
0003 E0 MOVX A,@DPTR
0004 FE MOV R6,A
0005 A3 INC DPTR
0006 E0 MOVX A,@DPTR
0007 8E00 R MOV px,R6
0009 F500 R MOV px+01H,A
Keil Software — Cx51 Compiler User’s Guide 113
Function Declarations
Cx51 provides you with a number of extensions for standard C function
declarations. These extensions allow you to:
where:
return_type is the type of the value returned from the function.
If no type is specified, int is assumed.
funcname is the name of the function.
args is the argument list for the function.
small, compact, or large is the explicit memory model for the function.
reentrant indicates that the function is recursive or reentrant.
interrupt indicates that the function is an interrupt function.
using specifies which register bank the function uses.
Descriptions of these attributes and other features are described in detail in the
following sections.
114 Chapter 3. Language Extensions
The total stack space of the classic 8051 is limited: only 256 bytes maximum.
Rather than consume stack space with function parameters or arguments, Cx51
assigns a fixed memory location for each function parameter. When a function
is called, the caller must copy the arguments into the assigned memory locations
before transferring control to the desired function. The function then extracts its
3 parameters, as needed, from these fixed memory locations. Only the return
address is stored on the stack during this process. Interrupt functions require
more stack space because they must switch register banks and save the values of
a few registers on the stack.
NOTE
Cx51 allows you to use also extended stack areas that are available in some
enhanced 8051 variants. In this way the stack space can be increase to several
Kbytes.
NOTE
Some 8051 derivatives provide only 64 bytes of on-chip data memory; most
devices have just 256 bytes. Take this into consideration when determining
which memory model to use, because the amount of on-chip data and idata
memory used directly affects the amount of stack space.
Keil Software — Cx51 Compiler User’s Guide 115
The following table details the registers used for different argument positions
and data types.
Argument Number char, 1-byte ptr int, 2-byte ptr long, float generic ptr
1
2
R7
R5
R6 & R7
R4 & R5
R4—R7
R4—R7
R1—R3
R1—R3
3
3 R3 R2 & R3 R1—R3
If no registers are available for argument passing, fixed memory locations are
used for function parameters.
NOTE
If the first parameter of a function is of type bit, other parameters are not passed
in registers. This is because the parameters that can be passed in registers are
out of sequence with the numbering scheme shown above. For this reason, bit
parameters should be declared at the end of the argument list.
116 Chapter 3. Language Extensions
You may, however, specify which memory model to use for a single function by
including the small, compact, or large function attribute in the function
declaration. For example:
#pragma small /* Default to small model */
The advantage of functions using the SMALL memory model is that the local
data and function argument parameters are stored in the internal 8051 RAM.
Therefore, data access is very efficient. The internal memory is limited,
however. Occasionally, the limited amount of internal data memory available
when using the small model cannot satisfy the requirements of a very large
program, and other memory models must be used. In this situation, you may
declare that a function uses a different memory model, as shown above.
By specifying the function model attribute in the function declaration, you can
select which of the three possible reentrant stacks and frame pointers are used.
Stack access in the SMALL model is more efficient than in the LARGE model.
Keil Software — Cx51 Compiler User’s Guide 117
The using function attribute is used to specify which register bank a function
uses. For example:
3
void rb_function (void) using 3
{
.
.
.
}
The currently selected register bank is saved on the stack at function entry.
The specified register bank is set.
The former register bank is restored before the function is exited.
118 Chapter 3. Language Extensions
The following example shows how to specify the using function attribute and
what the generated assembly code for the function entry and exit looks like.
stmt level source
1
2 extern bit alarm;
3 int alarm_count;
4 extern void alfunc (bit b0);
5
6 void falarm (void) using 3 {
7 1 alarm_count++;
8 1 alfunc (alarm = 1);
9 1 }
In the previous example, the code starting at offset 0000h saves the initial PSW
on the stack and sets the new register bank. The code starting at offset 0015h
restores the original register bank by popping the original PSW from the stack.
The using attribute may not be used in functions that return a value in registers.
You must exercise extreme care to ensure that register bank switches are
performed only in carefully controlled areas. Failure to do so may yield
incorrect function results. Even when you use the same register bank, functions
declared with the using attribute cannot return a bit value.
Typically, the using attribute is most useful in functions that also specify the
interrupt attribute. It is most common to specify a different register bank for
each interrupt priority level. Therefore, you could use one register bank for all
non-interrupt code, one for the high-level interrupt, and one for the low-level
interrupt.
Keil Software — Cx51 Compiler User’s Guide 119
Upon reset, the 8051 loads the PSW with 00h which selects register bank 0. By
default, all non-interrupt functions use register bank 0. To change this, you
must:
NOTE
The Cx51 compiler does not and cannot detect a register bank mismatch
between functions. Therefore, make sure that functions using alternate register
banks call only other functions that do not assume a default register bank.
Interrupt Functions
The 8051 and its derivatives provide a number of hardware interrupts that may
be used for counting, timing, detecting external events, and sending and
receiving data using the serial interface. The standard interrupts found on an
8051 are listed in the following table:
As 8051 vendors created new parts, more interrupts were added. The Cx51
compiler supports interrupt functions for 32 interrupts (0-31). Use the interrupt
vector address in the following table to determine the interrupt number.
The Cx51 compiler provides you with a method of calling a C function when an
interrupt occurs. This support lets you create interrupt service routines in C.
You need only be concerned with the interrupt number and register bank
selection. The compiler automatically generates the interrupt vector and entry
and exit code for the interrupt routine. The interrupt function attribute, when
included in a declaration, specifies that the associated function is an interrupt
function. For example:
unsigned int interruptcnt;
unsigned char second;
}
}
3
The interrupt attribute takes as an argument an integer constant in the 0 to 31
value range. Expressions with operators and the interrupt attribute are not
allowed in function prototypes. The interrupt attribute affects the object code
of the function as follows:
The contents of the SFR ACC, B, DPH, DPL, and PSW, when required, are
saved on the stack at the function invocation time.
All working registers that are used in the interrupt function are stored on the
stack if a register bank is not specified with the using attribute.
The working registers and special registers that were saved on the stack are
restored before exiting the function.
The function is terminated by the 8051 RETI instruction.
122 Chapter 3. Language Extensions
The following sample program shows you how to use the interrupt attribute.
The program also shows you what the code generated to enter and exit the
interrupt function looks like. The using function attribute is also used in the
example to select a register bank different from that of the non-interrupt program
code. However, because no working registers are needed in this function, the
code generated to switch the register bank is eliminated by the optimizer.
stmt level source
3 7
8
1
1
alarm = 1;
}
In the example above, note that the ACC and PSW registers are saved at offset
0000h and restored at offset 0011h. Note also the RETI instruction generated
to exit the interrupt.
Keil Software — Cx51 Compiler User’s Guide 123
Reentrant Functions
A reentrant function can be shared by several processes at the same time. When
a reentrant function is executing, another process can interrupt the execution and
then begin to execute that same reentrant function. Normally, functions in Cx51
cannot be called recursively or in a fashion which causes reentrancy. The reason
for this limitation is that function arguments and local variables are stored in
fixed memory locations. The reentrant function attribute allows you to declare
functions that may be reentrant and, therefore, may be called recursively. For
example:
int calc (char i, int b) reentrant {
int x;
3 }
x = table [i];
return (x * b);
As in the above example, you may selectively define (using the reentrant
attribute) functions as being reentrant. For each reentrant function, a reentrant
stack area is simulated in internal or external memory depending upon the
memory model used, as follows:
Reentrant functions use the default memory model to determine which memory
space to use for the reentrant stack. You may specify (with the small, compact,
and large function attributes) which memory model to use for a function. Refer
to “Specifying the Memory Model for a Function” on page 116 for more
information about memory models and function declarations.
The following rules apply to functions declared with the reentrant attribute.
bit type function arguments may not be used. Local bit scalars are also not
available. The reentrant capability does not support bit-addressable variables.
Reentrant functions must not be called from alien functions.
Reentrant function cannot use the alien attribute specifier to enable PL/M-51
argument passing conventions. 3
A reentrant function may simultaneously have other attributes like using and
interrupt and may include an explicit memory model attribute (small,
compact, large).
Return addresses are stored in the 8051 hardware stack. Any other required
PUSH and POP operations also affect the 8051 hardware stack.
Reentrant functions using different memory models may be intermixed.
However, each reentrant function must be properly prototyped and must
include its memory model attribute in the prototype. This is necessary for
calling routines to place the function arguments in the proper reentrant stack.
Each of the three possible reentrant models contains its own reentrant stack
area and stack pointer. For example, if small and large reentrant functions
are declared in a module, both small and large reentrant stacks are created
along with two associated stack pointers (one for small and one for large).
The simulated stack used by reentrant functions has its own stack pointer which
is independent of the 8051 stack and stack pointer. The stack and stack pointer
are defined and initialized in the STARTUP.A51 file.
126 Chapter 3. Language Extensions
The following table details the stack pointer assembler variable name, data area,
and size for each of the three memory models.
The simulated stack area for reentrant functions is organized from top to bottom.
The 8051 hardware stack is just the opposite and is organized bottom to top.
3 When using the SMALL memory model, both the simulated stack and the 8051
hardware stack share the same memory area but from opposite directions.
The simulated stack and stack pointers are declared and initialized in the Cx51
startup code in STARTUP.A51 which can be found in the LIB subdirectory. You
must modify the startup code to specify which simulated stack(s) to initialize in
order to use reentrant functions. You can also modify the starting address for the
top of the simulated stack(s) in the startup code. Refer to “STARTUP.A51” on
page 144 for more information on reentrant function stack areas.
Keil Software — Cx51 Compiler User’s Guide 127
}
return (c);
3
You may also create functions in C that can be invoked by PL/M-51 routines.
To do this, use the alien function type specifier in the C function declaration.
For example:
alien char c_func (char a, int b) {
return (a * b);
}
Parameters and return values of PL/M-51 functions may be any of the following
types: bit, char, unsigned char, int, and unsigned int. Other types, including
long, float, and all types of pointers, can be declared in C functions with the
alien type specifier. However, use these types with care because PL/M-51 does
not directly support 32-bit binary integers or floating-point numbers.
For example:
void func (void) _task_ num _priority_ pri
where:
is a task ID number from 0 to 255 for RTX51 Full or 0 to 15
3 num
for RTX51 Tiny.
pri is the priority for the task. Refer to the RTX51 User’s Guide
or the RTX51 Tiny User’s Guide for more information.
Task functions must be declared with a void return type and a void argument list.
Keil Software — Cx51 Compiler User’s Guide 129
Chapter 4. Preprocessor
The preprocessor built into the Cx51 compiler handles directives found in the
source file. Cx51 supports all of the ANSI Standard C directives. This chapter
provides a brief overview of the directives and elements provided by the
preprocessor.
Directives
Preprocessor directives must be the first non-whitespace text specified on a line.
All directives are prefixed with the pound or number-sign character (‘#’). For
example:
#pragma
#include <stdio.h>
#define DEBUG 1
The following table lists the preprocessor directives and gives a brief description
of each.
4
Directive Description
define Defines a preprocessor macro or constant.
elif Initiates an alternative branch of the if condition, when the previous if, ifdef, ifndef,
or elif branch was not taken.
else Initiates an alternative branch when the previous if, ifdef, or ifndef branch was not
taken.
endif Ends an if, ifdef, ifndef, elif, or else block.
error Outputs an error message defined by the user. This directive instructs the
compiler to emit the specified error message.
ifdef Evaluates an expression for conditional compilation. The argument to be evaluated
is the name of a definition.
ifndef Same as ifdef but the evaluation succeeds if the definition is not defined.
if Evaluates an expression for conditional compilation.
include Reads source text from an external file. The notation sequence determines the
search sequence of the included files. Cx51 searches for include files specified
with less-than/greater-than symbols (‘<’ ‘>’) in the include file directory. Cx51
searches for include files specified with double-quotes (“ “) in the current directory.
line Specifies a line number together with an optional filename. These specifications
are used in error messages to identify the error position.
pragma Allows you to specify control directives that may be included on the C51 command
line. Pragmas may contain the same control directives that are specified on the
command line.
undef Deletes a preprocessor macro or constant definition.
130 Chapter 4. Preprocessor
Stringize Operator
The stringize or number-sign operator (‘#’), when used within a macro
definition, converts a macro parameter into a string constant. This operator may
be used only in a macro that has a specified argument or parameter list.
When the stringize operator immediately precedes the name of one of the macro
parameters, the parameter passed to the macro is enclosed within quotation
marks and is treated as a string literal. For example:
#define stringer(x) printf (#x "\n")
stringer (text)
Token-pasting operator
The token-pasting operator (##) within a macro definition combines two
arguments. It permits two separate tokens in the macro definition to be joined
into a single token.
paster (9);
This example shows the concatenation of token##n into token9. Both the
4
stringize and the token-pasting operators are used in this example.
132 Chapter 4. Preprocessor
Constant Description
_ _C51_ _ Version number of the Cx51 compiler (for example, 610 for version 6.10).
_ _DATE_ _ Date when the compilation was started.
_ _FILE_ _ Name of the file being compiled.
_ _LINE_ _ Current line number in the file being compiled.
_ _MODEL_ _ Memory model selected (0 for small, 1 for compact, 2 for large).
_ _TIME_ _ Time when the compilation was started.
__STDC_ _ Defined to 1 to indicate full conformance with the ANSI C Standard.
4
Keil Software — Cx51 Compiler User’s Guide 133
The Cx51 compiler directly supports the enhanced features of the following
8051-based microcontrollers:
The C51 compiler provides you with support for these CPUs through the use of
special libraries, library routines, and the MODxxx command-line directives.
These directives enable C51 to generate object code that takes advantage of the
enhancements mentioned above. Refer to “Chapter 2. Compiling with Cx51” on
5
page 19 for more information about these directives.
134 Chapter 5. 8051 Derivatives
The MODA2 control directive instructs the C51 compiler to generate code that
uses both data pointers in your program.
The C51 compiler uses at least one data pointer in an interrupt function. If an
interrupt function is compiled using the MODA2 directive, both data pointers
are saved on the stack. This happens even if the interrupt function uses only one
data pointer.
To conserve stack space, you may compile interrupt functions with the
NOMODA2 directive. The C51 compiler does not use the second data pointer
when this directive is used.
The MODDP2 control directive instructs the C51 compiler to generate code that
uses both data pointers in your program.
The C51 compiler uses at least one data pointer in an interrupt function. If an
interrupt function is compiled using the MODDP2 directive, both data pointers
are saved on the stack. This happens even if the interrupt function uses only one
data pointer.
To conserve stack space, you may compile interrupt functions with the
NOMODDP2 directive. The C51 compiler does not use the second data pointer
when this directive is used.
Keil Software — Cx51 Compiler User’s Guide 135
The MOD517 control directive instructs the C51 compiler to generate code that
utilizes the advanced features of these CPUs.
Data Pointers
The Infineon C515C, C517, C517A, and C509 provide 8 data pointers which can
be used to improve memory accesses. Using multiple data pointers can improve
the execution of library functions such as: memcpy, memmove, memcmp,
strcpy, and strcmp. The 8 data pointers of the C515C, C517, C517 and C509
can also reduce the stack load of interrupt functions.
C51 uses only 2 of the 8 data pointers at a time. In order to keep the stack load
in the interrupt routines low, C51 switches to 2 unused data pointers when
5
switching the register bank. In this case, the contents of the register DPSEL are
saved on the stack, and a new pair of data pointers is selected. Saving the data
pointers on the stack is no longer required.
If an interrupt routine does not switch to another register bank (for example, the
function is declared without the using attribute), the data pointers must be saved
on the stack (using 4 bytes of stack space). To keep the size of the stack as small
as possible, use the MOD517(NODP8) directive to compile the interrupt routine
and the functions called from within the interrupt. This generates code for the
interrupt that uses only one data pointer and, therefore, only 2 bytes of stack
space.
136 Chapter 5. 8051 Derivatives
High-speed Arithmetic
C51 uses the 32-bit and 16-bit arithmetic operations of the C517, C517A, and
C509 to improve performance of a number of math-intensive operations. C
language programs execute considerably faster when using either of these CPUs.
The following tables show execution times for various arithmetic operations and
compare the performance of the standard 8051 to that of the 80C517 CPU.
5 Signed/unsigned multiplication
Unsigned division
8051
C517
8051
LMUL
LMUL517
ULDIV
106
62
227
106
62
497
106
62
650
C517 ULDIV517 36 52 101
Signed division 8051 SLDIV 267 564 709
C517 SLDIV517 49 75 141
Left shift 8051 LSHL 5 237 470
C517 LSHL517 5 28 29
Unsigned right shift 8051 ULSHR 5 237 470
C517 ULSHR517 5 29 30
Signed right shift 8051 SLSHR 5 237 470
C517 — — — —
Times are shown in CPU cycles.
Keil Software — Cx51 Compiler User’s Guide 137
Floating-point Operations
Operation CPU Routine Min. Avg. Max.
Addition 8051 FPADD 8 107 202
C517 FPADD517 8 107 202
Subtraction 8051 FPSUB 11 113 214
C517 FPSUB517 11 113 214
Multiplication 8051 FPMUL 13 114 198
C517 FPMUL517 13 86 141
Division 8051 FPDIV 48 687 999
C517 FPDIV517 48 165 209
Comparison 8051 FPCMP 42 54 59
C517 FPCMP517 42 54 59
Square root 8051 SQRT 12 1936 2360
C517 SQRT517 12 755 882
Sine 8051 SIN 1565 2928 3476
C517 SIN517 1422 2519 3048
Cosine 8051 COS 1601 2921 3665
C517 COS517 1458 2514 3180
Tangent 8051 TAN 1982 4966 5699
C517 TAN517 1839 3753 4329
Arcsine 8051 ASIN 912 6991 8554
C517 ASIN517 912 3984 4717
Arccosine 8051 ACOS 796 7578 8579
C517 ACOS517 796 4255 4871
Arctangent
Exponential
8051
C517
8051
ATAN
ATAN517
EXP
1069
1037
233
3320
2444
3314
3712
2737
5308
5
C517 EXP517 176 2879 4724
Natural Logarithm 8051 LOG 32 3432 4128
C517 LOG517 32 2405 2926
Common Logarithm 8051 LOG10 34 3607 4328
C517 LOG10517 34 2530 3069
ASCII to float conversion 8051 FPATOF 960 3006 5611
C517 FPATOF517 722 2202 4144
Times are shown in CPU cycles.
138 Chapter 5. 8051 Derivatives
NOTES
The execution times specified in the preceding tables do not take access times for
variables or stack operations into consideration. Actual processing times may
consume up to 100 additional cycles depending on the stack load and address
space used.
When using the arithmetic features of the C517, C517A and C509, note that
operations involving the arithmetic processor are exclusive and may not be
interrupted. Do not use the arithmetic extensions in both the main program and
an interrupt service routine.
Use the following suggestions to help guarantee that only one thread of
execution uses the arithmetic processor:
Library Routines
5 The extra features of the C517, C517A and C509 are used in several library
routines to enhance performance. These routines are listed below and are
described in detail in “Chapter 8. Library Reference” on page 205.
Note that the following restrictions apply when creating programs for the
8xC750, 8xC751, and 8xC752:
Stream functions such as printf and putchar may not be used. These
functions are usually not necessary for this chip because it is only equipped
with a maximum of 2 KBytes and has no serial interface.
Floating-point operations may not be used. Only operations using char,
unsigned char, int, unsigned int, long, unsigned long, and bit data types
are allowed.
The C51 compiler must be invoked with the ROM(SMALL) control 5
directive. This control statement instructs the C51 compiler to use only
AJMP and ACALL instructions.
The library file 80C751.LIB must be included in the input module list of the
linker. For example:
BL51 myprog.obj, startup751.obj, 80C751.LIB
The MODP2 control directive instructs the C51 compiler to generate code that
uses both data pointers in your program.
The C51 compiler uses at least one data pointer in an interrupt function. If an
interrupt function is compiled using the MODP2 directive, both data pointers are
saved on the stack. This happens even if the interrupt function uses only one
data pointer.
To conserve stack space, you may compile interrupt functions with the
NOMODP2 directive. The C51 compiler does not use the second data pointer
when this directive is used.
5
Keil Software — Cx51 Compiler User’s Guide 141
5
Keil Software — Cx51 Compiler User’s Guide 143
Files you can alter to customize the startup procedures or run-time execution
of several library routines in your target program
The conventions Cx51 uses to name code and data segments
How to interface Cx51 functions to assembly and PL/M-51 routines
Data storage formats for the different Cx51 data types
Different optimizing features of the Cx51 optimizing compiler
Customization Files
The Cx51 compiler includes a number of source files you can modify to adapt
your target program to a specific hardware platform. These files contain: code
that is executed upon startup (STARTUP.A51), code that is used to initialize static
variables (INIT.A51), and code that is used to perform low-level stream I/O
6
(GETKEY.C and PUTCHAR.C). Source code for the memory allocation routines
is also included in the files CALLOC.C, FREE.C, INIT_MEM.C, MALLOC.C, and
REALLOC.C. All of these source files are described in detail in the sections that
follow.
The code contained in these files is already compiled or assembled and included
in the C library. When you link, the code from the library is automatically
included.
To include custom startup or initialization routines, you must include them in the
linker command line. The following example shows you how to include custom
replacement files for STARTUP.A51 and PUTCHAR.C.
BL51 MYMODUL1.OBJ, MYMODUL2.OBJ, STARTUP.OBJ, PUTCHAR.OBJ
144 Chapter 6. Advanced Programming Techniques
STARTUP.A51
The STARTUP.A51 file contains the startup code for a Cx51 target program. This
source file is located in the LIB directory. Include a copy of this file in each
8051 project that needs custom startup code.
This code is executed immediately upon reset of the target system and optionally
performs the following operations, in order:
The STARTUP.A51 file provides you with assembly constants that you may
change to control the actions taken at startup. These are defined in the following
table.
;
; To link the modified STARTUP.OBJ file to your application use
; the following BL51 invocation:
;
; BL51 <your object file list>, STARTUP.OBJ <controls>
;
;-----------------------------------------------------------------
; User-defined Power-On Initialization of Memory
;
; With the following EQU statements the initialization of memory
; at processor reset can be defined:
;
; the absolute start-address of IDATA memory is always 0
IDATALEN EQU 80H ; the length of IDATA memory in bytes.
;
XDATASTART EQU 0H ; the absolute start-address of XDATA memory
XDATALEN EQU 0H ; the length of XDATA memory in bytes.
;
PDATASTART EQU 0H ; the absolute start-address of PDATA memory
PDATALEN EQU 0H ; the length of PDATA memory in bytes.
;
; Notes: The IDATA space overlaps physically the DATA and BIT
; areas of the 8051 CPU. At minimum the memory space occupied from
; the C-51 run-time routines must be set to zero.
;-----------------------------------------------------------------
; Reentrant Stack Initialization
;
; The following EQU statements define the stack pointer for
; reentrant functions and initialized it:
;
; Stack Space for reentrant functions in the SMALL model.
IBPSTACK EQU 0 ; set to 1 if small reentrant is used.
IBPSTACKTOP EQU 0FFH+1 ; set top of stack to highest location+1.
;
; Stack Space for reentrant functions in the LARGE model.
XBPSTACK EQU 0 ; set to 1 if large reentrant is used.
XBPSTACKTOP EQU 0FFFFH+1 ; set top of stack to highest location+1.
;
; Stack Space for reentrant functions in the COMPACT model.
6 PBPSTACK
PBPSTACKTOP
EQU 0 ; set to 1 if compact reentrant is used.
EQU 0FFFFH+1 ; set top of stack to highest location+1.
;-----------------------------------------------------------------
; Page Definition for Using the Compact Model with 64 KByte xdata
; RAM
;
; The following EQU statements define the xdata page used for pdata
; variables. The EQU PPAGE must conform with the PPAGE control used
; in the linker invocation.
;
PPAGEENABLE EQU 0 ; set to 1 if pdata object are used.
PPAGE EQU 0 ; define PPAGE number.
;-----------------------------------------------------------------
NAME ?C_STARTUP
RSEG ?STACK
DS 1
PUBLIC ?C_STARTUP
CSEG AT 0
?C_STARTUP: LJMP STARTUP1
RSEG ?C_C51STARTUP
STARTUP1:
IF IDATALEN <> 0
MOV R0,#IDATALEN - 1
CLR A
IDATALOOP: MOV @R0,A
DJNZ R0,IDATALOOP
ENDIF
IF XDATALEN <> 0
MOV DPTR,#XDATASTART
MOV R7,#LOW (XDATALEN)
IF (LOW (XDATALEN)) <> 0
MOV R6,#(HIGH XDATALEN) +1
ELSE
MOV R6,#HIGH (XDATALEN)
ENDIF
CLR A
XDATALOOP: MOVX @DPTR,A
INC DPTR
DJNZ R7,XDATALOOP
DJNZ R6,XDATALOOP
ENDIF
IF PPAGEENABLE <> 0
MOV P2,#PPAGE
ENDIF
IF PDATALEN <> 0
MOV R0,#PDATASTART
MOV R7,LOW (PDATALEN)
CLR A
PDATALOOP: MOVX @R0,A
ENDIF
INC
DJNZ
R0
R7,PDATALOOP 6
IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)
IF XBPSTACK <> 0
EXTRN DATA (?C_XBP)
IF PBPSTACK <> 0
EXTRN DATA (?C_PBP)
MOV ?C_PBP,#LOW PBPSTACKTOP
ENDIF
148 Chapter 6. Advanced Programming Techniques
MOV SP,#?STACK-1
LJMP ?C_START
END
START751.A51
The START751.A51 file contains the startup code for a C51 target program that is
to run on the Signetics 8xC751 CPU. This source file is located in the LIB
directory. To use this file, follow the instructions on how to use STARTUP.A51 in
the previous section. The only difference between the two files is that
START751.A51 is specifically used for the 8xC751 which cannot access more
than 2 KBytes of code space and can access no external data memory. For these
reasons, there are no assembler constants that can affect xdata and pdata
memory.
6 ;
;
;
BL51 <your object file list>, START751.OBJ <controls>
;-------------------------------------------------------------------------
;
; User-defined Power-On Initialization of Memory
;
; With the following EQU statements the initialization of memory
; at processor reset can be defined:
;
; the absolute start-address of IDATA memory is always 0
IDATALEN EQU 40H ; the length of IDATA memory in bytes.
;
; Notes: The IDATA space physically overlaps the DATA and BIT areas of
; the 80751 CPU. At minimum the memory space occupied by C51
; run-time routines must be set to zero.
;-------------------------------------------------------------------------
;
; Reentrant Stack Initialization
;
; The following EQU statements define the stack pointer for reentrant
; functions and initialized it:
Keil Software — Cx51 Compiler User’s Guide 149
;
; Stack Space for reentrant functions in the SMALL model.
IBPSTACK EQU 0 ; set to 1 if small reentrant is used.
IBPSTACKTOP EQU 0FFH+1 ; set top of stack to highest location+1.
;
;-------------------------------------------------------------------------
NAME ?C_STARTUP
RSEG ?STACK
DS 1
CSEG AT 0
?C_STARTUP: AJMP STARTUP1
RSEG ?C_C51STARTUP
STARTUP1:
IF IDATALEN <> 0
MOV R0,#IDATALEN - 1
CLR A
IDATALOOP: MOV @R0,A
DJNZ R0,IDATALOOP
ENDIF
IF IBPSTACK <> 0
EXTRN DATA (?C_IBP)
MOV
AJMP
SP,#?STACK-1
?C_START
6
END
150 Chapter 6. Advanced Programming Techniques
INIT.A51
The INIT.A51 file contains the initialization routine for variables that were
explicitly initialized. If your system is equipped with a watchdog timer, you can
integrate a watchdog refresh into the initialization code using the watchdog
macro. This macro need be defined only if the initialization takes longer than
the watchdog cycle time. If you are using an 80515, the macro could be defined
as follows:
WATCHDOG MACRO
SETB WDT
SETB SWDT
ENDM
6
;
; If the C application contains many initialized variables & uses a
; watchdog it might be possible that the user has to include a watchdog
; refresh into the initialization process. The watchdog refresh routine
; can be defined in the following MACRO and can alter all CPU registers
; except DPTR.
WATCHDOG MACRO
; Include any Watchdog refresh code here
ENDM
;-------------------------------------------------------------------------
?C_START:
MOV DPTR,#?C_INITSEG
LOOP:
WATCHDOG
CLR A
MOV R6,#1
MOVC A,@A+DPTR
JZ INITEND
.
.
.
Keil Software — Cx51 Compiler User’s Guide 151
INIT751.A51
The INIT751.A51 file contains the initialization routine for variables that were
explicitly initialized. Use this initialization routine for the Signetics 8xC751.
The following is a listing of the INIT751.A51 file.
;-------------------------------------------------------------------------
; This file is part of the C51 Compiler package
;
;-------------------------------------------------------------------------
; INIT751.A51: This code is executed, if the application program
; contains initialized variables at file level.
;
; To translate this file use A51 with the following invocation:
;
; A51 INIT751.A51
;
; To link the modified INIT.OBJ file to your application use the
; following BL51 invocation:
;
; BL51 <your object file list>, INIT751.OBJ <controls>
;
;-------------------------------------------------------------------------
NAME ?C_INIT
INITEND:
RSEG
AJMP MAIN
?C_C51STARTUP
6
IorPData: ; If CY=1 PData Values
CLR A
MOVC A,@A+DPTR
INC DPTR
MOV R0,A ; Start Address
IorPLoop: CLR A
MOVC A,@A+DPTR
INC DPTR
MOV @R0,A
Common: INC R0
DJNZ R7,IorPLoop
SJMP Loop
Bits: CLR A
MOVC A,@A+DPTR
INC DPTR
MOV R0,A
ANL A,#007H
ADD A,#Table-LoadTab
152 Chapter 6. Advanced Programming Techniques
XCH A,R0
CLR C
RLC A ; Bit Condition to Carry
SWAP A
ANL A,#00FH
ORL A,#20H ; Bit Address
XCH A,R0 ; convert to Byte Address
MOVC A,@A+PC
LoadTab: JC SetIt
CPL A
ANL A,@R0
SJMP BitReady
SetIt: ORL A,@R0
BitReady: MOV @R0,A
DJNZ R7,Bits
SJMP Loop
Table: DB 00000001B
DB 00000010B
DB 00000100B
DB 00001000B
DB 00010000B
DB 00100000B
DB 01000000B
DB 10000000B
6 MOVC
INC
JZ
A,@A+DPTR
DPTR
NOBIG
INC R6
NOBIG: XCH A,R7
ANL A,#0C0H ; Typ is in Bit 6 and Bit 7
ADD A,ACC
JZ IorPDATA
JC Bits
SJMP $
RSEG ?C_INITSEG
DB 0
END
Keil Software — Cx51 Compiler User’s Guide 153
PUTCHAR.C
This file contains the putchar function which is the low-level character output
routine for the stream I/O routines. All stream routines that output character data
do so through this routine. You may adapt this routine to your individual
hardware (for example, LCD or LED displays).
The default PUTCHAR.C file delivered with the Cx51 compiler outputs
characters via the serial interface. An XON/XOFF protocol is used for flow
control. Linefeed characters (‘\n’) are automatically converted into carriage
return/linefeed sequences (‘\r\n’).
GETKEY.C
This file contains the _getkey function which is the low-level character input
routine for the stream I/O routines. All stream routines that input character data
do so through this routine. You may adapt this routine to your individual
hardware (for example, for matrix keyboards). The default GETKEY.C file
delivered with the Cx51 compiler reads a character via the serial interface. No
data conversions are performed.
CALLOC.C
This file contains the source code for the calloc function. This routine allocates
memory for an array from the memory pool.
6
FREE.C
This file contains the source code for the free function. This routine returns a
previously allocated memory block to the memory pool.
INIT_MEM.C
This file contains the source code for the init_mempool function. This routine
allows you to specify the location and size of a memory pool from which
memory may be allocated using the malloc, calloc, and realloc functions.
154 Chapter 6. Advanced Programming Techniques
MALLOC.C
This file contains the source code for the malloc function. This routine allocates
memory from the memory pool.
REALLOC.C
This file contains the source code for the realloc function. This routine resizes a
previously allocated memory block.
6
Keil Software — Cx51 Compiler User’s Guide 155
Optimizer
The Cx51 compiler is an optimizing compiler. This means that the compiler
takes certain steps to ensure that the code that is generated and output to the
object file is the most efficient (smaller and/or faster) code possible. The
compiler analyzes the generated code to produce more efficient instruction
sequences. This ensures that your Cx51 program runs as quickly as possible.
The Cx51 compiler provides six different levels of optimizing. Each increasing
level includes the optimizations of the levels below it.
Level Description
0 Constant Folding: The compiler performs calculations that reduce expressions to
numeric constants, where possible. This includes calculations of run-time addresses.
Simple Access Optimizing: The compiler optimizes access of internal data and bit
addresses in the 8051 system.
Jump Optimizing: The compiler always extends jumps to the final target. Jumps to
jumps are deleted.
1 Dead Code Elimination: Unused code fragments and artifacts are eliminated.
Jump Negation: Conditional jumps are closely examined to see if they can be
streamlined or eliminated by the inversion of the test logic.
2 Data Overlaying: Data and bit segments suitable for static overlay are identified and
internally marked. The BL51 Linker/Locator has the capability, through global data
flow analysis, of selecting segments which can then be overlaid.
3 Peephole Optimizing: Redundant MOV instructions are removed. This includes
unnecessary loading of objects from the memory as well as load operations with
constants. Complex operations are replaced by simple operations when memory
4
space or execution time can be saved.
Register Variables: Automatic variables and function arguments are located in
registers when possible. Reservation of data memory for these variables is omitted.
6
Extended Access Optimizing: Variables from the IDATA, XDATA, PDATA and
CODE areas are directly included in operations. The use of intermediate registers is
not necessary most of the time.
Simple Loop Optimizing: Program loops that fill a memory range with a constant are
converted and optimized.
156 Chapter 6. Advanced Programming Techniques
Level Description
6 Loop Rotation: Program loops are rotated if the resulting program code is faster and
more efficient.
7 Extended Access Optimization: In addition, uses the DPTR for register variables.
Pointer and array accesses are optimized for both speed
and code size.
8
General Optimizations
Optimization Description
Constant Folding Several constant values occurring in an expression or
address calculation are combined as a constant.
Jump Optimizing Jumps are inverted or extended to the final target address
when the program efficiency is thereby increased.
Dead Code Elimination Code which cannot be reached (dead code) is removed from
the program.
Register Variables Automatic variables and function arguments are located in
registers when possible. Reservation of data memory for
these variables is omitted.
Parameter Passing Via Registers A maximum of three function arguments can be passed in
registers.
Global Common Subexpression Identical subexpressions or address calculations that occur
Elimination multiple times in a function are recognized and calculated
only once when possible.
8051-Specific Optimizations
6 Optimization Description
Peephole Optimization Complex operations are replaced by simplified operations when
memory space or execution time can be saved as a result.
Extended Access Optimizing Constants and variables are included directly in operations.
Data Overlaying Data and bit segments of functions are identified as
OVERLAYABLE and are overlaid with other data and bit
segments by the BL51 Linker/Locator.
Case/Switch Optimizing Any switch and case statements are optimized by using a jump
table or string of jumps.
Keil Software — Cx51 Compiler User’s Guide 157
6
158 Chapter 6. Advanced Programming Techniques
Each segment name has a prefix that corresponds to the memory type used for
the segment. The prefix is enclosed in question marks (?). The following is a
list of the standard segment name prefixes:
6 ?ID?
?PD?
idata
pdata
Indirectly-addressable internal data memory
Paged data in external data memory
?XD? xdata xdata memory (RAM space)
?XC? const xdata xdata memory (constant ROM space)
Data Objects
Data objects are the variables and constants you declare in your C programs.
Cx51 generates a separate segment for each memory type for which a variable is
declared. The following table lists the segment names generated for different
variable data objects.
Program Objects
Program objects include the code generated for C program functions by the
Cx51 compiler. Each function in a source module is assigned a separate code
segment using the ?PR?function_name?module_name naming convention. For
example, the function error_check in the file SAMPLE.C would result in a
segment name of ?PR?ERROR_CHECK?SAMPLE.
Segments are also created for local variables that are declared within the body of
a function. These segment names follow the above conventions and have a
different prefix depending upon the memory area in which the local variables are
stored.
Function arguments were historically passed using fixed memory locations. This
is still true for routines written in PL/M-51. However, Cx51 can pass up to 3
function arguments in registers. Other arguments are passed using the traditional
fixed memory areas. Memory space is reserved for all function arguments
6
regardless of whether or not some of these arguments may be passed in registers.
The parameter areas must be publicly known to any calling module. So, they are
publicly defined using the following segment names:
?function_name?BYTE
?function_name?BIT
For example, if func1 is a function that accepts both bit arguments as well as
arguments of other data types, the bit arguments are passed starting at
?FUNC1?BIT, and all other parameters are passed starting at ?FUNC1?BYTE.
Refer to “Interfacing C Programs to Assembler” on page 161 for examples of the
function argument segments.
160 Chapter 6. Advanced Programming Techniques
Functions that have parameters, local variables, or bit variables contain all
additional segments for these variables. These segments can be overlaid by the
BL51 Linker/Locator.
The names for functions with register parameters and reentrant attributes are
modified slightly to avoid run-time errors. The following table lists deviations
from the standard segment names.
There are several reasons why you might want to call an assembly routine from
your C program. You may have assembly code already written that you wish to
use, you may need to improve the speed of a particular function, or you may
want to manipulate SFRs or memory-mapped I/O devices directly from
assembly. This section describes how to write assembly routines that can be
directly interfaced to C programs.
Function Parameters
By default, C functions pass up to three parameters in registers. The remaining 6
parameters are passed in fixed memory locations. You may use the directive
NOREGPARMS to disable parameter passing in registers. Parameters are
passed in fixed memory locations if parameter passing in registers is disabled or
if there are too many parameters to fit in registers. Functions that pass
parameters in registers are flagged by Cx51 with an underscore character (‘_’)
prefixed to the function name at code generation time. Functions that pass
parameters only in fixed memory locations are not prefixed with an underscore.
Refer to “Using the SRC Directive” on page 164 for an example.
162 Chapter 6. Advanced Programming Techniques
Arg Number char, 1-byte ptr int, 2-byte ptr long, float generic ptr
1 R7 R6 & R7 R4—R7 R1—R3
(MSB in R6, (Mem type in R3,
LSB in R7) MSB in R2,
LSB in R1)
2 R5 R4 & R5 R4—R7 R1—R3
(MSB in R4, (Mem type in R3,
LSB in R5) MSB in R2,
LSB in R1)
3 R3 R2 & R3 R1—R3
(MSB in R2, (Mem type in R3,
LSB in R3) MSB in R2,
LSB in R1)
The following examples clarify how registers are selected for parameter passing.
Declaration Description
func1 ( The first and only argument, a, is passed in registers R6 and R7.
int a)
func2 ( The first argument, b, is passed in registers R6 and R7. The second
int b, argument, c, is passed in registers R4 and R5. The third argument, d, is
int c, passed in registers R1, R2, and R3.
6 int
func3 (
*d)
long e,
The first argument, e, is passed in registers R4, R5, R6, and R7. The
second argument, f, cannot be located in registers since those available for
long f) a second parameter with a type of long are already used by the first argument.
This parameter is passed using fixed memory locations.
func4 ( The first argument, g, passed in registers R4, R5, R6, and R7. The second
float g, parameter, h, cannot be passed in registers and is passed in fixed memory
char h) locations.
Keil Software — Cx51 Compiler User’s Guide 163
The fixed memory locations used for parameter passing may be in internal data
memory or external data memory depending upon the memory model used. The
small memory model is the most efficient and uses internal data memory for
parameter segments. The compact and large models use external data memory
for the parameter passing segments.
R4-R7
MSB in R6, LSB in R7
generates the following assembly output file when compiled using the SRC
directive.
; ASM1.SRC generated from: ASM1.C
NAME ASM1
RSEG ?PR?_asmfunc1?ASM1
USING 0
6
_asmfunc1:
;---- Variable 'arg?00' assigned to Register 'R6/R7' ----
; SOURCE LINE # 4
; SOURCE LINE # 6
; return (1 + arg);
; SOURCE LINE # 7
MOV A,R7
ADD A,#01H
MOV R7,A
CLR A
ADDC A,R6
MOV R6,A
; }
; SOURCE LINE # 8
?C0001:
RET
; END OF _asmfunc1
END
Keil Software — Cx51 Compiler User’s Guide 165
In this example, note that the function name, asmfunc1, is prefixed with an
underscore character signifying that arguments are passed in registers. The arg
parameter is passed using R6 and R7.
The following example shows the assembly source generated for the same
function; however, register parameter passing has been disabled using the
NOREGPARMS directive.
; ASM2.SRC generated from: ASM2.C
NAME ASM2
RSEG ?DT?asmfunc1?ASM2
?asmfunc1?BYTE:
arg?00: DS 2
; #pragma SRC
; #pragma SMALL
; #pragma NOREGPARMS
;
; unsigned int asmfunc1 (
RSEG ?PR?asmfunc1?ASM2
USING 0
asmfunc1:
; SOURCE LINE # 5
; SOURCE LINE # 7
; return (1 + arg);
; SOURCE LINE # 8
MOV A,arg?00+01H
ADD A,#01H
6
MOV R7,A
CLR A
ADDC A,arg?00
MOV R6,A
; }
; SOURCE LINE # 9
?C0001:
RET
; END OF asmfunc1
END
Note in this example that the function name, asmfunc1, is not prefixed with an
underscore character and that the arg parameter is passed in the
?asmfunc1?BYTE segment.
166 Chapter 6. Advanced Programming Techniques
Register Usage
Assembler functions can change all register contents in the current selected
register bank as well as the contents of the registers ACC, B, DPTR, and PSW.
When invoking a C function from assembly, assume that these registers may be
destroyed by the C function that is called.
Overlaying Segments
If the overlay process is executed during program linking and locating, it is
important that each assembler subroutine have a unique program segment. This
is necessary so that during the overlay process, the references between the
functions are calculated using the references of the individual segments. The
data areas of the assembler subprograms may be included in the overlay analysis
when the following points are observed:
All segment names must be created using the Cx51 segment naming
conventions.
Each assembler function with local variables must be assigned its own data
segment. This data segment may be accessed by other functions only for
passing parameters. Parameters must be passed in order.
Example Routines
6 The following program examples show you how to pass parameters to and from
assembly routines. The following C functions are used in all of these examples:
int function (
int v_a, /* passed in R6 & R7 */
char v_b, /* passed in R5 */
bit v_c, /* passed in fixed memory location */
long v_d, /* passed in fixed memory location */
bit v_e); /* passed in fixed memory location */
Keil Software — Cx51 Compiler User’s Guide 167
The following are two assembly code examples. The first shows how the
example function is invoked from assembly. The second example displays the
assembly code for the example function.
6
Keil Software — Cx51 Compiler User’s Guide 169
The following are two assembly code examples. The first shows you how the
example function is invoked from assembly. The second example displays the
assembly code for the example function.
; Store int
6
MOV intresult+1,R7 ; Retval
.
.
.
170 Chapter 6. Advanced Programming Techniques
6 .
.
MOVX @R0,A
.
MOV R6,#HIGH retval ; Return value
MOV R7,#LOW retval ; int constant
RET ; Return
Keil Software — Cx51 Compiler User’s Guide 171
The following are two assembly code examples. The first shows you how the
example function is invoked from assembly. The second example displays the
assembly code for the example function.
; Store int
6
MOV intresult+1,R7 ; Retval
.
.
.
172 Chapter 6. Advanced Programming Techniques
6 .
.
.
MOV R6,#HIGH retval ; Return value
MOV R7,#LOW retval ; int constant
RET ; Return
Keil Software — Cx51 Compiler User’s Guide 173
Cx51 can optionally operate with PL/M-51 parameter passing conventions. The
alien function type specifier is used to declare public or external functions that
are compatible with PL/M-51 in any memory model. For example:
extern alien char plm_func (int, char);
Parameters and return values of PL/M-51 functions may be any of the following
types: bit, char, unsigned char, int, and unsigned int. Other types, including
long, float, and all types of pointers, can be declared in C functions with the
alien type specifier. However, use these types with care because PL/M-51 does
not directly support 32-bit binary integers or floating-point numbers.
Other data types, like structures and unions, may contain scalars from this table.
All elements of these data types are allocated sequentially and are byte-aligned
due to the 8-bit architecture of the 8051 family.
6
Bit Variables
Scalars of type bit are stored using a single bit. Pointers to and arrays of bit are
not allowed. Bit objects are always located in the bit-addressable internal
memory space of the 8051 CPU. The BL51 Linker/Locator overlays bit objects
if possible.
Keil Software — Cx51 Compiler User’s Guide 175
Address +0 +1
Contents 0x12 0x34
Address +0 +1 +2
Contents Memory Type Offset; High-Order Byte Offset; Low-Order Byte
Depending on the compiler version that you are using the memory type byte has
the following values:
The format of the generic pointers is also used for pointers with the memory type
far. Therefore, any other memory type values are may be used to address far
memory space.
The following example shows the memory storage of a generic pointer (on the
C51 compiler) that references address 0x1234 in the xdata memory area.
6 Address +0 +1 +2
Contents 0x01 0x12 0x34
Keil Software — Cx51 Compiler User’s Guide 177
Floating-point Numbers
Scalars of type float are stored using 4 bytes (32 bits). The format used
corresponds to that of the IEEE-754 standard.
There are two components of a floating-point number: the mantissa and the
exponent. The mantissa stores the actual digits of the number. The exponent
stores the power to which the mantissa must be raised. The exponent is an 8-bit
value in the 0 to 255 range and is stored relative to 127. The actual value of the
exponent is calculated by subtracting 127 from the stored value (0 to 255). The
value of the exponent can be anywhere from +128 to -127. The mantissa is a
24-bit value whose most significant bit (MSB) is always 1 and is, therefore, not
stored. There is also a sign bit which indicates if the floating-point number is
positive or negative.
Floating-point numbers are stored in 8051 memory using the following format:
Address +0 +1 +2 +3
Contents SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
where:
S represents the sign bit where 1 is negative and 0 is positive.
E is the two’s complement exponent with an offset of 127.
M is the 23-bit normal mantissa. The highest bit is always 1
and, therefore, is not stored
6
Using the above format, the floating-point number -12.5 would be stored as a
hexadecimal value of 0xC1480000. In memory, this appears as follows:
Address +0 +1 +2 +3
Contents 0xC1 0x48 0x00 0x00
Address +0 +1 +2 +3
Format SEEEEEEE EMMMMMMM MMMMMMMM MMMMMMMM
Binary 11000001 01001000 00000000 00000000
Hex C1 48 00 00
10010000000000000000000
There is an understood decimal point at the left of the mantissa that is always
preceded by a 1. This digit is not stored in the hexadecimal representation of
the floating-point number. Adding 1 and the decimal point to the beginning of
the mantissa gives the following:
1.10010000000000000000000
Now, adjust the mantissa for the exponent. A negative exponent moves the
6 decimal point to the left. A positive exponent moves the decimal point to the
right. Because the exponent is 3, the mantissa is adjusted as follows:
1100.10000000000000000000
The result is now a binary floating-point number. Binary digits left of the
decimal point represent the power of two corresponding to the position: 1100
represents (1 × 23) + (1 × 22) + (0 × 21) + (0 × 20) which equals 12.
Binary digits that are right of the decimal point also represent the power of two
corresponding to their position. However, the powers are negative: .100…
represents (1 × 2-1) + (0 × 2-2) + (0 × 2-3) + … which equals .5.
Adding these values together gives 12.5 which must be negated since the sign
bit is set. So, the floating-point hexadecimal value 0xC1480000 is -12.5.
Keil Software — Cx51 Compiler User’s Guide 179
Floating-point Errors
The 8051 does not contain an interrupt vector to trap floating-point errors;
therefore, your software must appropriately respond to these error conditions. In
addition to the normal floating-point values, a floating-point number may contain
a binary error value. These values are defined as a part of the IEEE standard and
are used whenever an error occurs during normal processing of floating-point
operations. Your code should check for possible arithmetic errors at the end of
each floating-point operation.
NOTE
The Cx51 library function _chkfloat_ lets you quickly check floating-point
status.
This union contains a float and an unsigned long in order to perform floating-
point math operations and to respond to the IEEE error states. For example:
#define NaN 0xFFFFFFFF /* Not a number (error) */
6
#define plusINF 0x7F800000 /* Positive overflow */
#define minusINF 0xFF800000 /* Negative overflow */
union f {
float f; /* Floating-point value */
unsigned long ul; /* Unsigned long value */
};
x.f = a * b;
if (x.ul == NaN || x.ul == plusINF || x.ul == minusINF) {
/* handle the error */
}
else {
/* result is correct */
180 Chapter 6. Advanced Programming Techniques
}
}
The Cx51 compiler generates an object file for ALMCTRL.C and includes a
segment for variables in the xdata memory area. Because it is the only variable
declared in this module, alarm_control is the only variable in that segment.
The name of the segment is ?XD?ALMCTRL.
The BL51 Linker/Locator allows you to specify the base address of any segment
by using the location control directives. Because the alarm_control variable
was declared to reside in xdata, the XDATA BL51 directive must be used as
6
follows:
BL51 … almctrl.obj XDATA(?XD?ALMCTRL(2000h)) …
There are linker directives for locating segments in the code, xdata, pdata,
idata, and data memory areas. Refer to the 8051 Utilities User’s Guide for
more information about the Linker/Locator.
182 Chapter 6. Advanced Programming Techniques
6
Keil Software — Cx51 Compiler User’s Guide 183
Debugging
By default, the C51 compiler uses the Intel Object Format (OMF-51) for object
files and generates complete symbol information. All Intel compatible emulators
may be used for program debugging. The DEBUG control directive embeds
debugging information in the object file. In addition, the OBJECTEXTEND
control directive embeds additional variable type information in the object file
which allows type-specific display of variables and structures when using certain
emulators.
The CX51 compiler uses the OMF2 object file format. The OMF2 format is also
used by the C51 compiler when the directive OMF2 is active. The OMF2 format
requires the extended LX51 linker/locater and cannot be used with the BL51
linker/locater. The OMF2 object file format provides extensive debug
information and is supported by the µVision2 debugger and some emulators.
6
Keil Software — Cx51 Compiler User’s Guide 185
Fatal Errors
Fatal errors cause immediate termination of the compilation. These errors
normally occur as the result of invalid options specified on the command line.
Fatal errors are also generated when the compiler cannot access a specified
source include file.
C51 FATAL-ERROR -
ACTION: <current action>
LINE: <line in which the error is detected>
ERROR: <corresponding error message>
C51 TERMINATED.
C51 FATAL-ERROR -
ACTION: <current action>
FILE: <file in which the error is detected>
ERROR: <corresponding error message>
C51 TERMINATED.
The following are descriptions of the possible text for the Action and Error
fields in the above messages.
7
186 Chapter 7. Error Messages
Actions
ALLOCATING MEMORY
The compiler could not allocate enough memory to compile the specified
source file.
CREATING LIST-FILE / OBJECT-FILE / WORKFILE
The compiler could not create the list file, object file, or work file. This error
may occur if the disk is full or write-protected, or if the file already exists and
is read only.
GENERATING INTERMEDIATE CODE
The source file contains a function that is too large to be translated into
pseudo-code by the compiler. Try breaking the function into smaller
functions and re-compiling.
OPENING INPUT-FILE
The compiler failed to find or open the selected source or include file.
PARSING INVOKE-/#PRAGMA-LINE
An error was detected while evaluating arguments on the command line or
while evaluating parameters in a #pragma statement.
PARSING SOURCE-FILE / ANALYZING DECLARATIONS
The source file contains too many external references. Reduce the number of
external variables and functions accessed by the source file.
WRITING TO FILE
An error was encountered while writing to the list file, object file, or work
file.
7
Keil Software — Cx51 Compiler User’s Guide 187
Errors
'(' AFTER CONTROL EXPECTED
Some control parameters need an argument enclosed in parentheses. This
message is displayed when the left parenthesis is missing.
')' AFTER PARAMETER EXPECTED
This message indicates that the right parenthesis of the enclosed argument is
missing.
BAD DIGIT IN NUMBER
The numerical argument of a control parameter contains invalid characters.
Only decimal digits are acceptable.
CAN'T CREATE FILE
The filename defined on the FILE line cannot be created.
CAN'T HAVE GENERAL CONTROL IN INVOCATION LINE
General controls (for example, EJECT) cannot be included on the command
line. Place these controls in the source file using the #pragma statement.
FILE DOES NOT EXIST
The filename defined on the FILE line, cannot be found.
FILE WRITE-ERROR
An error occurred while writing to the list, preprint, work, or object file
because of insufficient disk space.
IDENTIFIER EXPECTED
This message is generated when the DEFINE control has no arguments.
DEFINE requires an identifier as its argument. This is the same convention
as in the C language.
MEMORY SPACE EXHAUSTED
The compiler could not allocate enough memory to compile the specified
source file. If you receive this message consistently, you should break the
source file into two or more smaller files and re-compile.
MORE THAN 100 ERRORS IN SOURCE-FILE
7
During the compilation more than 100 errors were detected. This causes the
termination of the compiler.
MORE THAN 256 SEGMENTS/EXTERNALS
More than 256 total references were encountered in a source file. A single
source file cannot contain more than 256 functions or external references.
This is a historical restriction mandated by the Intel Object Module Format
(OMF-51). Functions which contain scalar and/or bit declarations produce
two and sometimes three segment definitions in the object file.
188 Chapter 7. Error Messages
7
Keil Software — Cx51 Compiler User’s Guide 189
Syntax and semantic errors produce a message in the list file. These error
messages are in the following format:
where:
number is the error number.
line corresponds to the line number in the source file or include
file.
file is the name of the source or include file in which the error
was detected.
error message is descriptive text and is dependent upon the type of error
encountered.
The following table lists syntax and semantic errors by error number. The error
message displayed is listed along with a brief description and possible cause and
correction.
7 140
values.
Bit in illegal memory-space
Definitions of bit scalars may contain the optional memory type data. If the
memory type is missing then the type data is assumed, because bits always
reside in the internal data memory. This error can occur when an attempt is made
to use another data type with a bit scalar definition.
141 Syntax error near token: expected other_token, …
The token seen by the compiler is wrong. Depending upon the context the
expected token is displayed.
142 Invalid base address
The base-address of an sfr or sbit declaration is in error. Valid bases are values
in the 0x80 to 0xFF range. If the declaration uses the notation base^pos, then the
base address must also be a multiple of eight.
Keil Software — Cx51 Compiler User’s Guide 191
OR / Compound OR (|, |=)
AND / Compound AND (&, &=)
XOR / Compound XOR (^, ^=)
7
Compare bit with bit or constant (==, !=)
Negation (~)
bit operands may be used in expressions with other data types. In this case a
type cast is automatically performed.
194 ‘*’ indirection to object of unknown size
The indirection operator * may not be used with void pointers because the object
size, which the pointer refers to, is unknown.
195 ‘*’ illegal indirection
The * operator may not be applied on non-pointer arguments.
194 Chapter 7. Error Messages
7
exception to this rule is when all parameters can be passed in registers. This is
due to the method of parameter passing employed by Cx51. The name of the
called function must be known because parameters are written into the data
segment of the called function. For indirect calls, however, the name of the called
function is not known.
213 Left side of asn-op not an lvalue
The address of a changeable object is required at the right side of the assignment
operator.
214 Illegal pointer conversion
Objects of type bit, float or aggregates cannot be converted to pointers.
215 Illegal type conversion
Struct/union/void cannot be converted to any other types.
Keil Software — Cx51 Compiler User’s Guide 195
233
The specified label is already defined.
Undefined label
This message indicates a label that was accessed but was not defined.
7
Sometimes this message appears several lines after the actual label reference.
This is caused by the method used to search for undefined labels.
234 ‘{‘, scope stack overflow(31)
The maximum of 31 nested blocks has been exceeded. Additional levels of
nested blocks are ignored.
235 Parameter <number>: different types
Parameter types in the function declaration are different from those in the function
prototype.
196 Chapter 7. Error Messages
7
249 Segment <name>: Segment too large
The compiler detected a data segment that was too large. The maximum size of a
data segment depends on memory space.
250 ‘\esc’; value exceeds 255
An escape sequence in a string constant exceeds the valid value range. The
maximum value is 255.
251 Illegal octal digit
The specified character is not a valid octal digit.
252 Misplaced primary control, line ignored
Primary controls must be specified at the start of the C module before any
#include directives or declarations.
Keil Software — Cx51 Compiler User’s Guide 197
7
A spaced pointer has been assigned another spaced pointer with a different
memory space. For example:
#pragma asm
.
.
.
assembler instruction(s)
.
.
.
#pragma endasm
Keil Software — Cx51 Compiler User’s Guide 199
Warnings
Warnings produce information about potential problems which may occur during
the execution of the resulting program. Warnings do not hinder compilation of
the source file.
Warnings produce a message in the list file. These warning messages are in the
following format:
where:
number is the error number.
line corresponds to the line number in the source file or include
file.
file is the name of the source or include file in which the error
was detected.
warning message is descriptive text that is dependent upon the type of warning
encountered.
The following table lists warnings by number. The warning message displayed
is listed along with a brief description and possible cause and correction.
The compiler has no way to check for missing or excessive parameters and their
types. Include prototypes of the functions used in your program. Prototypes must
be specified before the functions are actually called. The definition of a function
automatically produces a prototype.
209 Too few actual parameters
Too few actual parameters were included in a function call.
219 Long constant truncated to int
The value of a constant expression must be capable of being represented by an int
type.
245 Unknown pragma, line ignored
The #pragma statement is unknown, so the entire pragma line is ignored.
258 Mspace illegal on struct/union member
Mspace on parameter ignored
A member of a structure or a parameter may not contain the specification of a
memory type. The object to which the pointer refers may, however, contain a
memory type. For example:
7 265
the virtual stack.
‘name’: recursive call to non-reentrant function
A direct recursion to a non-reentrant function was discovered. This can be
intentional but should be functionally checked (through the generated code) for
each individual case. Indirect recursions are discovered by the linker/locator.
Keil Software — Cx51 Compiler User’s Guide 203
#pragma asm
.
.
.
assembler instruction(s)
.
.
.
#pragma endasm
275 Expression with possibly no effect
The compiler detected an expression which does not generate code. For example:
7
parameters were used. Excess parameters are ignored.
317 Macro ‘name’: invalid redefinition
A predefined macro cannot be redefined or removed. The compiler recognizes the
following predefined macros:
7
Keil Software — Cx51 Compiler User’s Guide 205
Intrinsic Routines
The Cx51 compiler supports a number of intrinsic library functions.
Non-intrinsic functions generate ACALL or LCALL instructions to perform the
library routine. Intrinsic functions generate in-line code to perform the library
routine. The generated in-line code is much faster and more efficient than a
called routine would be. The following functions are available in intrinsic form:
8
206 Chapter 8. Library Reference
Library Files
The Cx51 library includes six different compile-time libraries which are
optimized for various functional requirements. These libraries support most of
the ANSI C function calls.
Several library modules are provided in source code form. These routines are
used to perform low-level hardware-related I/O for the stream I/O functions.
You can find the source for these routines in the LIB directory. You may
modify these source files and substitute them for the library routines. By using
these routines, you can quickly adapt the library to perform (using any hardware
I/O device available in your target) stream I/O. Refer to “Stream Input and
Output” on page 217 for more information.
8
C51 Compiler 207
Standard Types
The C51 standard library contains definitions for a number of standard types
which may be used by the library routines. These standard types are declared in
include files which you may access from your C programs.
jmp_buf
The jmp_buf type is defined in SETJMP.H and specifies the buffer used by the
setjmp and longjmp routines to save and restore the program environment. The
jmp_buf type is defined as follows:
#define _JBLEN 7
typedef char jmp_buf[_JBLEN];
va_list
The va_list array type is defined in STDARG.H. This type holds data required by
the va_arg and va_end routines. The va_list type is defined as follows:
typedef char *va_list;
8
208 Chapter 8. Library Reference
CBYTE
The CBYTE macro allows you to access individual bytes in the program
memory of the 8051 and is defined as follows:
#define CBYTE ((unsigned char volatile code *)0)
CWORD
The CWORD macro allows you to access individual words in the program
memory of the 8051 and is defined as follows:
#define CWORD ((unsigned int volatile code *) 0)
NOTE
The index used with this macro does not represent the memory address of the
8 integer value. To obtain the memory address, you must multiply the index by the
sizeof an integer (2 bytes).
C51 Compiler 209
DBYTE
The DBYTE macro allows you to access individual bytes in the internal data
memory of the 8051 and is defined as follows:
#define DBYTE ((unsigned char volatile idata *) 0)
to read or write the contents of the byte in internal data memory at address
0002h.
DWORD
The DWORD macro allows you to access individual words in the internal data
memory of the 8051 and is defined as follows:
#define DWORD ((unsigned int volatile idata *) 0)
to read or write the contents of the word in internal data memory at address
0004h (2 × sizeof (unsigned int) = 4).
NOTE
The index used with this macro does not represent the memory address of the
integer value. To obtain the memory address, you must multiply the index by the
sizeof an integer (2 bytes).
8
210 Chapter 8. Library Reference
PBYTE
The PBYTE macro allows you to access individual bytes in one page of the
external data memory of the 8051 and is defined as follows:
#define PBYTE ((unsigned char volatile pdata *) 0)
to read or write the contents of the byte in pdata memory at address 0002h.
PWORD
The PWORD macro allows you to access individual words in one page of the
external data memory of the 8051 and is defined as follows:
#define PWORD ((unsigned int volatile pdata*) 0)
to read or write the contents of the word in pdata memory at address 0004h
(2 × sizeof (unsigned int) = 4).
NOTE
The index used with this macro does not represent the memory address of the
integer value. To obtain the memory address, you must multiply the index by the
sizeof an integer (2 bytes).
8
C51 Compiler 211
XBYTE
The XBYTE macro allows you to access individual bytes in the external data
memory of the 8051 and is defined as follows:
#define XBYTE ((unsigned char volatile xdata*) 0)
to read or write the contents of the byte in external data memory at address
0002h.
XWORD
The XWORD macro allows you to access individual words in the external data
memory of the 8051 and is defined as follows:
#define XWORD ((unsigned int volatile xdata*) 0)
to read or write the contents of the word in external data memory at address
0004h (2 × sizeof (unsigned int) = 4).
NOTE
The index used with this macro does not represent the memory address of the
integer value. To obtain the memory address, you must multiply the index by the
sizeof an integer (2 bytes).
8
212 Chapter 8. Library Reference
Routines by Category
This sections gives a brief overview of the major categories of routines available
in the Cx51 standard library. Refer to “Reference” on page 227 for a complete
description of routine syntax and usage.
NOTE
Many of the routines in the Cx51 standard library are reentrant, intrinsic, or
both. These specifications are listed under attributes in the following tables.
Unless otherwise noted, routines are non-reentrant and non-intrinsic.
Buffer Manipulation
Routine Attributes Description
memccpy Copies data bytes from one buffer to another until a
specified character or specified number of characters has
been copied.
memchr reentrant Returns a pointer to the first occurrence of a specified
character in a buffer.
memcmp reentrant Compares a given number of characters from two different
buffers.
memcpy reentrant Copies a specified number of data bytes from one buffer
to another.
memmove reentrant Copies a specified number of data bytes from one buffer
to another.
memset reentrant Initializes a specified number of data bytes in a buffer to a
specified character value.
8
C51 Compiler 213
The character conversion and classification routines allow you to test individual
characters for a variety of attributes and convert characters to different formats.
The _tolower, _toupper, and toascii routines are implemented as macros. All
other routines are implemented as functions. All macro definitions and function
prototypes are found in the CTYPE.H include file.
8
214 Chapter 8. Library Reference
Data Conversion
Routine Attributes Description
abs reentrant Generates the absolute value of an integer type.
atof / atof517 Converts a string to a float.
atoi Converts a string to an int.
atol Converts a string to a long.
cabs reentrant Generates the absolute value of a character type.
labs reentrant Generates the absolute value of a long type.
strtod / Converts a string to a float.
strtod517
strtol Converts a string to a long.
strtoul Converts a string to an unsigned long.
Math
Routine Attributes Description
acos / acos517 Calculates the arc cosine of a specified number.
asin / asin517 Calculates the arc sine of a specified number.
atan / atan517 Calculates the arc tangent of a specified number.
atan2 Calculates the arc tangent of a fraction.
ceil Finds the integer ceiling of a specified number.
cos / cos517 Calculates the cosine of a specified number.
cosh Calculates the hyperbolic cosine of a specified number.
exp / exp517 Calculates the exponential function of a specified number.
fabs reentrant Finds the absolute value of a specified number.
floor Finds the largest integer less than or equal to a specified
number.
8 fmod
log / log517
Calculates the floating-point remainder.
Calculates the natural logarithm of a specified number.
log10 / log10517 Calculates the common logarithm of a specified number.
modf Generates integer and fractional components of a
specified number.
pow Calculates a value raised to a power.
C51 Compiler 215
All of these routines are implemented as functions. Most are prototyped in the
include file MATH.H. Functions which end in 517 (acos517, asin517, atan517,
cos517, exp517, log517, log10517, sin517, sqrt517, and tan517) are prototyped
in the 80C517.H include file. The rand and srand functions are prototyped in the
STDLIB.H include file.
The _chkfloat_, _crol_, _cror_, _irol_, _iror_, _lrol_, and _lror_ functions are
prototyped in the INTRINS.H include file.
8
216 Chapter 8. Library Reference
Memory Allocation
Routine Attributes Description
calloc Allocates storage for an array from the memory pool.
free Frees a memory block that was allocated using calloc,
malloc, or realloc.
init_mempool Initializes the memory location and size of the memory
pool.
malloc Allocates a block from the memory pool.
realloc Reallocates a block from the memory pool.
The memory allocation functions provide you with a means to specify, allocate,
and free blocks of memory from a memory pool. All memory allocation
functions are implemented as functions and are prototyped in the STDLIB.H
include file.
Before using any of these functions to allocate memory, you must first specify,
using the init_mempool routine, the location and size of a memory pool from
which subsequent memory requests are satisfied.
The calloc and malloc routines allocate blocks of memory from the pool. The
calloc routine allocates an array with a specified number of elements of a given
size and initializes the array to 0. The malloc routine allocates a specified
number of bytes.
The realloc routine changes the size of an allocated block, while the free routine
returns a previously allocated memory block to the memory pool.
8
C51 Compiler 217
The stream input and output routines allow you to read and write data to and
from the 8051 serial interface or a user-defined I/O interface. The default
_getkey and putchar functions found in the Cx51 library read and write
characters using the 8051 serial interface. You can find the source for these
functions in the LIB directory. You may modify these source files and
substitute them for the library routines. When this is done, other stream
functions then perform input and output using the new _getkey and putchar
routines.
If you want to use the existing _getkey and putchar functions, you must first
initialize the 8051 serial port. If the serial port is not properly initialized, the
default stream functions do not function. Initializing the serial port requires
manipulating special function registers SFRs of the 8051. The include file
REG51.H contains definitions for the required SFRs.
8
218 Chapter 8. Library Reference
The following example code must be executed immediately after reset, before
any stream functions are invoked.
.
.
.
#include <reg51.h>
.
.
.
SCON = 0x50; /* Setup serial port control register */
/* Mode 1: 8-bit uart var. baud rate */
/* REN: enable receiver */
The stream routines treat input and output as streams of individual characters.
There are routines that process characters as well as functions that process
strings. Choose the routines that best suit your requirements.
All of these routines are implemented as functions. Most are prototyped in the
STDIO.H include file. The printf517, scanf517, sprintf517, and sscanf517
functions are prototyped in the 80C517.H include file.
8
C51 Compiler 219
String Manipulation
Routine Attributes Description
strcat Concatenates two strings.
strchr reentrant Returns a pointer to the first occurrence of a specified
character in a string.
strcmp reentrant Compares two strings.
strcpy reentrant Copies one string to another.
strcspn Returns the index of the first character in a string that
matches any character in a second string.
strlen reentrant Returns the length of a string.
strncat Concatenates up to a specified number of characters from
one string to another.
strncmp Compares two strings up to a specified number of
characters.
strncpy Copies up to a specified number of characters from one
string to another.
strpbrk Returns a pointer to the first character in a string that
matches any character in a second string.
strpos reentrant Returns the index of the first occurrence of a specified
character in a string.
strrchr reentrant Returns a pointer to the last occurrence of a specified
character in a string.
strrpbrk Returns a pointer to the last character in a string that
matches any character in a second string.
strrpos reentrant Returns the index of the last occurrence of a specified
character in a string.
strspn Returns the index of the first character in a string that
does not match any character in a second string.
The string routines are implemented as functions and are prototyped in the
STRING.H include file. They perform the following operations:
Copying strings
Appending one string to the end of another
Comparing two strings
Locating one or more characters from a specified set in a string
The variable-length argument list routines are implemented as macros and are
defined in the STDARG.H include file. These routines provide you with a
portable method of accessing arguments in a function that takes a variable
number of arguments. These macros conform to the ANSI C Standard for
variable-length argument lists.
Miscellaneous
Routine Attributes Description
setjmp reentrant Saves the current stack condition and program address.
longjmp reentrant Restores the stack condition and program address.
_nop_ intrinsic, Inserts an 8051 NOP instruction.
reentrant
_testbit_ intrinsic, Tests the value of a bit and clears it to 0.
reentrant
Routines found in the miscellaneous category do not fit easily into any other
library routine category. The setjmp and longjmp routines are implemented as
functions and are prototyped in the STDJMP.H include file.
The _nop_ and _testbit_ routines are used to direct the compiler to generate a
NOP instruction and a JBC instruction respectively. These routines are
prototyped in the INTRINS.H include file.
8
C51 Compiler 221
Include Files
The include files that are provided with the C51 standard library are found in the
INC subdirectory. These files contain constant and macro definitions, type
definitions, and function prototypes. The following sections describe the use
and contents of each include file. Macros and functions included in the file are
listed as well.
Within the µVision2 editor context menu that opens on a right mouse click in a
editor window, you can insert the SFR defintion that matches the selected
device.
SFR definition files for all 8051 variants can be downloaded from
www.keil.com. The device database available on this web page contains the
header file for the Special Function Registers file of almost all 8051 devices.
80C517.H
The 80C517.H include file contains routines that use the enhanced operational
features of the 80C517 CPU and its derivatives. These routines are:
ABSACC.H
The ABSACC.H include file contains definitions for macros that allow you to
directly access the different memory areas of the 8051.
8
Keil Software — Cx51 Compiler User’s Guide 223
ASSERT.H
The ASSERT.H include file defines the assert macro you can use to create test
conditions in your programs.
CTYPE.H
The CTYPE.H include file contains definitions and prototypes for routines
which classify ASCII characters and routines which perform character
conversions. The following is a list of these routines:
INTRINS.H
The INTRINS.H include file contains prototypes for routines that instruct the
compiler to generate in-line intrinsic code.
MATH.H
The MATH.H include file contains prototypes and definitions for all routines
that perform floating-point math calculations. Other math functions are also
included in this file. All of the math function routines are listed below:
tanh
8
Keil Software — Cx51 Compiler User’s Guide 225
SETJMP.H
The SETJMP.H include file defines the jmp_buf type and prototypes the setjmp
and longjmp routines which use it.
STDARG.H
The STDARG.H include file defines macros that allow you to access arguments in
functions with variable-length argument lists. The macros include:
STDDEF.H
The STDDEF.H include file defines the offsetof macro you can use to determine
the offset of members of a structure.
STDIO.H
The STDIO.H include file contains prototypes and definitions for stream I/O
routines. They are:
The STDIO.H include file also defines the EOF manifest constant.
8
226 Chapter 8. Library Reference
STDLIB.H
The STDLIB.H include file contains prototypes and definitions for the type
conversion and memory allocation routines listed below:
The STDLIB.H include file also defines the NULL manifest constant.
STRING.H
The STRING.H include file contains prototypes for the following string and
buffer manipulation routines:
The STRING.H include file also defines the NULL manifest constant.
8
Keil Software — Cx51 Compiler User’s Guide 227
Reference
The following pages constitute the C51 standard library reference. The routines
included in the standard library are described here in alphabetical order and each
is divided into several sections:
8
228 Chapter 8. Library Reference
abs
Summary: #include <math.h>
int abs (
int val); /* number to take absolute value
of */
Return Value: The abs function returns the absolute value of val.
x = -42;
y = abs (x);
8
Keil Software — Cx51 Compiler User’s Guide 229
acos / acos517
Summary: #include <math.h>
float acos (
float x); /* number to calculate arc
cosine of */
8
230 Chapter 8. Library Reference
asin / asin517
Summary: #include <math.h>
float asin (
float x); /* number to calculate arc sine
of */
8
Keil Software — Cx51 Compiler User’s Guide 231
assert
Summary: #include <assert.h>
void assert (
expression);
void check_parms (
char *string)
{
assert (string != NULL); /* check for NULL ptr */
printf ("String %s is OK\n", string);
}
8
232 Chapter 8. Library Reference
atan / atan517
Summary: #include <math.h>
float atan (
float x); /* number to calculate arc
tangent of */
8
Keil Software — Cx51 Compiler User’s Guide 233
atan2
Summary: #include <math.h>
float atan2 (
float y, /* denominator for arc tangent */
float x); /* numerator for arc tangent */
void tst_atan2 () {
float x;
float y;
float z;
x = -1.0;
8
234 Chapter 8. Library Reference
atof / atof517
Summary: #include <stdlib.h>
float atof (
void *string); /* string to convert */
Return Value: The atof function returns the floating-point value that is
produced by interpreting the characters in string as a
number.
8 }
f = atof (s);
printf ("ATOF(%s) = %f\n", s, f);
Keil Software — Cx51 Compiler User’s Guide 235
atoi
Summary: #include <stdlib.h>
int atoi (
void *string); /* string to convert */
Return Value: The atoi function returns the integer value that is produced
by interpreting the characters in string as a number.
i = atoi (s);
printf ("ATOI(%s) = %d\n", s, i);
}
8
236 Chapter 8. Library Reference
atol
Summary: #include <stdlib.h>
long atol (
void *string); /* string to convert */
Description: The atol function converts string into a long integer value.
The input string is a sequence of characters that can be
interpreted as a long. This function stops processing
characters from string at the first one it cannot recognize as
part of the number.
The atol function requires string to have the following
format:
whitespace {+ | -} digits
where:
Return Value: The atol function returns the long integer value that is
produced by interpreting the characters in string as a
number.
l = atol (s);
printf ("ATOL(%s) = %ld\n", s, l);
8
Keil Software — Cx51 Compiler User’s Guide 237
cabs
Summary: #include <math.h>
char cabs (
char val); /* character to take absolute value of */
Return Value: The cabs function returns the absolute value of val.
x = -23;
y = cabs (x);
8
238 Chapter 8. Library Reference
calloc
Summary: #include <stdlib.h>
void *calloc (
unsigned int num, /* number of items */
unsigned int len); /* length of each item */
NOTE
Source code is provided for this routine in the LIB
directory. You can modify the source to customize this
function for your hardware environment. Refer to
“Chapter 6. Advanced Programming Techniques” on page
143 for more information.
if (p == NULL)
printf ("Error allocating array\n");
else
printf ("Array address is %p\n", (void *) p);
8
Keil Software — Cx51 Compiler User’s Guide 239
ceil
Summary: #include <math.h>
float ceil (
float val); /* number to calculate ceiling for */
Description: The ceil function calculates the smallest integer value that is
greater than or equal to val.
Return Value: The ceil function returns a float that contains the smallest
integer value that is not less than val.
x = 45.998;
y = ceil (x);
8
240 Chapter 8. Library Reference
_chkfloat_
Summary: #include <intrins.h>
unsigned char _chkfloat_ (
float val); /* number for error checking */
8
Keil Software — Cx51 Compiler User’s Guide 241
cos / cos517
Summary: #include <math.h>
float cos (
float x); /* number to calculate cosine
for */
Return Value: The cos function returns the cosine for the value x.
8
242 Chapter 8. Library Reference
cosh
Summary: #include <math.h>
float cosh (
float x); /* value for hyperbolic cos
function */
Return Value: The cosh function returns the hyperbolic cosine for the
value x.
8
Keil Software — Cx51 Compiler User’s Guide 243
_crol_
Summary: #include <intrins.h>
unsigned char _crol_ (
unsigned char c, /* character to rotate left */
unsigned char b); /* bit positions to rotate */
Description: The _crol_ routine rotates the bit pattern for the character c
left b bits. This routine is implemented as an intrinsic
function. The code required is included in-line rather than
being called.
a = 0xA5;
8
244 Chapter 8. Library Reference
_cror_
Summary: #include <intrins.h>
unsigned char _cror_ (
unsigned char c, /* character to rotate right */
unsigned char b); /* bit positions to rotate */
Description: The _cror_ routine rotates the bit pattern for the character c
right b bits. This routine is implemented as an intrinsic
function. The code required is included in-line rather than
being called.
a = 0xA5;
8
Keil Software — Cx51 Compiler User’s Guide 245
exp / exp517
Summary: #include <math.h>
float exp (
float x); /* power to use for ex function
*/
Description: The exp function calculates the exponential function for the
floating-point value x.
Return Value: The exp function returns the floating-point value ex.
x = 4.605170186;
8
246 Chapter 8. Library Reference
fabs
Summary: #include <math.h>
float fabs (
float val); /* number to calc absolute value for */
Return Value: The fabs function returns the absolute value of val.
x = 10.2;
y = fabs (x);
printf ("FABS(%f) = %f\n", x, y);
x = -3.6;
y = fabs (x);
printf ("FABS(%f) = %f\n", x, y);
8
Keil Software — Cx51 Compiler User’s Guide 247
floor
Summary: #include <math.h>
float floor (
float val); /* value for floor function */
Description: The floor function calculates the largest integer value that is
less than or equal to val.
Return Value: The floor function returns a float that contains the largest
integer value that is not greater than val.
x = 45.998;
y = floor (x);
8
248 Chapter 8. Library Reference
fmod
Summary: #include <math.h>
float fmod (
float x, /* value to calculate modulo for */
float y); /* integer portion of modulo */
Description: The fmod function returns a value f such that f has the
same sign as x, the absolute value of f is less than the
absolute value of y, and there exists an integer k such that
k*y+f equals x. If the quotient x / y cannot be represented,
the result is undefined.
8
Keil Software — Cx51 Compiler User’s Guide 249
free
Summary: #include <stdlib.h>
void free (
void xdata *p); /* block to free */
NOTE
Source code for this routine is located in the folder
\KEIL\C51\LIB. You may modify the source to customize this
function for your particular hardware environment. Refer
to “Chapter 6. Advanced Programming Techniques” on
page 143 for more information.
if (mbuf == NULL) {
printf ("Unable to allocate memory\n");
}
else {
free (mbuf);
printf ("Memory free\n");
}
}
8
250 Chapter 8. Library Reference
getchar
Summary: #include <stdio.h>
char getchar (void);
Description: The getchar function reads a single character from the input
stream using the _getkey function. The character read is
then passed to the putchar function to be echoed.
NOTE
This function is implementation-specific and is based on the
operation of the _getkey and/or putchar functions. These
functions, as provided in the standard library, read and
write characters using the serial port of the 8051. Custom
functions may use other I/O devices.
8
Keil Software — Cx51 Compiler User’s Guide 251
_getkey
Summary: #include <stdio.h>
char _getkey (void);
NOTE
This routine is implementation-specific, and its function may
deviate from that described above. Source is included for
the _getkey and putchar functions which may be modified to
provide character level I/O for any hardware device. Refer
to “Customization Files” on page 143 for more information.
8
252 Chapter 8. Library Reference
gets
Summary: #include <stdio.h>
char *gets (
char *string, /* string to read */
int len); /* maximum characters to read
*/
Description: The gets function calls the getchar function to read a line of
characters into string. The line consists of all characters up
to and including the first newline character (‘\n’). The
newline character is replaced by a null character (‘\0’) in
string.
NOTE
This function is implementation-specific and is based on the
operation of the _getkey and/or putchar functions. These
functions, as provided in the standard library, read and
write characters using the serial port of the 8051. Custom
functions may use other I/O devices.
do {
gets (buf, sizeof (buf));
printf ("Input string \"%s\"", buf);
} while (buf [0] != '\0');
8 }
Keil Software — Cx51 Compiler User’s Guide 253
init_mempool
Summary: #include <stdlib.h>
void init_mempool (
void xdata *p, /* start of memory pool */
unsigned int size); /* length of memory pool */
NOTE
This function must be used to setup the memory pool before
any other memory management functions (calloc, free,
malloc, realloc) can be called. Call the init_mempool
function only once at the beginning of your program.
p = malloc (100);
8
for (i = 0; i < 100; i++) ((char *) p)[i] = i;
free (p);
}
254 Chapter 8. Library Reference
_irol_
Summary: #include <intrins.h>
unsigned int _irol_ (
unsigned int i, /* integer to rotate left */
unsigned char b); /* bit positions to rotate */
Description: The _irol_ routine rotates the bit pattern for the integer i
left b bits. This routine is implemented as an intrinsic
function. The code required is included in-line rather than
being called.
a = 0xA5A5;
8
Keil Software — Cx51 Compiler User’s Guide 255
_iror_
Summary: #include <intrins.h>
unsigned int _iror_ (
unsigned int i, /* integer to rotate right */
unsigned char b); /* bit positions to rotate */
Description: The _iror_ routine rotates the bit pattern for the integer i
right b bits. This routine is implemented as an intrinsic
function. The code required is included in-line rather than
being called.
a = 0xA5A5;
8
256 Chapter 8. Library Reference
isalnum
Summary: #include <ctype.h>
bit isalnum (
char c); /* character to test */
8
Keil Software — Cx51 Compiler User’s Guide 257
isalpha
Summary: #include <ctype.h>
bit isalpha (
char c); /* character to test */
8
258 Chapter 8. Library Reference
iscntrl
Summary: #include <ctype.h>
bit iscntrl (
char c); /* character to test */
8
Keil Software — Cx51 Compiler User’s Guide 259
isdigit
Summary: #include <ctype.h>
bit isdigit (
char c); /* character to test */
8
260 Chapter 8. Library Reference
isgraph
Summary: #include <ctype.h>
bit isgraph (
char c); /* character to test */
8
Keil Software — Cx51 Compiler User’s Guide 261
islower
Summary: #include <ctype.h>
bit islower (
char c); /* character to test */
8
262 Chapter 8. Library Reference
isprint
Summary: #include <ctype.h>
bit isprint (
char c); /* character to test */
8
Keil Software — Cx51 Compiler User’s Guide 263
ispunct
Summary: #include <ctype.h>
bit ispunct (
char c); /* character to test */
8
264 Chapter 8. Library Reference
isspace
Summary: #include <ctype.h>
bit isspace (
char c); /* character to test */
8
Keil Software — Cx51 Compiler User’s Guide 265
isupper
Summary: #include <ctype.h>
bit isupper (
char c); /* character to test */
8
266 Chapter 8. Library Reference
isxdigit
Summary: #include <ctype.h>
bit isxdigit (
char c); /* character to test */
8
Keil Software — Cx51 Compiler User’s Guide 267
labs
Summary: #include <math.h>
long labs (
long val); /* value to calc. abs. value for */
Description: The labs function determines the absolute value of the long
integer val.
Return Value: The labs function returns the absolute value of val.
x = -12345L;
y = labs (x);
8
268 Chapter 8. Library Reference
log / log517
Summary: #include <math.h>
float log (
float val); /* value to take natural logarithm of */
Description: The log function calculates the natural logarithm for the
floating-point number val. The natural logarithm uses the
base e or 2.718282…
Return Value: The log function returns the floating-point natural logarithm
of val.
x = 2.71838;
x *= x;
y = log (x); /* y = 2 */
8
Keil Software — Cx51 Compiler User’s Guide 269
log10 / log10517
Summary: #include <math.h>
float log10 (
float val); /* value to take common logarithm of */
Description: The log10 function calculates the common logarithm for the
floating-point number val. The common logarithm uses
base 10.
x = 1000;
y = log10 (x); /* y = 3 */
8
270 Chapter 8. Library Reference
longjmp
Summary: #include <setjmp.h>
void longjmp (
jmp_buf env, /* environment to restore */
int retval); /* return value */
8
Keil Software — Cx51 Compiler User’s Guide 271
trigger ();
}
}
8
272 Chapter 8. Library Reference
_lrol_
Summary: #include <intrins.h>
unsigned long _lrol_ (
unsigned long l, /* 32-bit integer to rotate left */
unsigned char b); /* bit positions to rotate */
Description: The _lrol_ routine rotates the bit pattern for the long integer
l left b bits. This routine is implemented as an intrinsic
function. The code required is included in-line rather than
being called.
a = 0xA5A5A5A5;
8
Keil Software — Cx51 Compiler User’s Guide 273
_lror_
Summary: #include <intrins.h>
unsigned long _lror_ (
unsigned long l, /* 32-bit int to rotate right */
unsigned char b); /* bit positions to rotate */
Description: The _lror_ routine rotates the bit pattern for the long integer
l right b bits. This routine is implemented as an intrinsic
function. The code required is included in-line rather than
being called.
a = 0xA5A5A5A5;
8
274 Chapter 8. Library Reference
malloc
Summary: #include <stdlib.h>
void *malloc (
unsigned int size); /* block size to allocate */
NOTE
Source code is provided for this routine in the LIB
directory. You may modify the source to customize this
function for your hardware environment. Refer to
“Chapter 6. Advanced Programming Techniques” on page
143 for more information.
Return Value: The malloc function returns a pointer to the allocated block
or a null pointer if there was not enough memory to satisfy
the allocation request.
if (p == NULL)
printf ("Not enough memory space\n");
else
printf ("Memory allocated\n");
8
Keil Software — Cx51 Compiler User’s Guide 275
memccpy
Summary: #include <string.h>
void *memccpy (
void *dest, /* destination buffer */
void *src, /* source buffer */
char c, /* character which ends copy */
int len); /* maximum bytes to copy */
Return Value: The memccpy function returns a pointer to the byte in dest
that follows the last character copied or a null pointer if the
last character copied was c.
void *c;
if (c == NULL)
printf ("'g' was not found in the src
buffer\n");
else
printf ("characters copied up to 'g'\n");
8
276 Chapter 8. Library Reference
memchr
Summary: #include <string.h>
void *memchr (
void *buf, /* buffer to search */
char c, /* byte to find */
int len); /* maximum buffer length */
Description: The memchr function scans buf for the character c in the
first len bytes of the buffer.
void *c;
if (c == NULL)
printf ("'g' was not found in the buffer\n");
else
printf ("found 'g' in the buffer\n");
8
Keil Software — Cx51 Compiler User’s Guide 277
memcmp
Summary: #include <string.h>
char memcmp (
void *buf1, /* first buffer */
void *buf2, /* second buffer */
int len); /* maximum bytes to compare
*/
Value Meaning
<0 buf1 less than buf2
=0 but1 equal to buf2
>0 buf1 greater than buf2
char i;
if (i < 0)
printf ("hexchars < hexchars2\n");
else if (i > 0)
printf ("hexchars > hexchars2\n");
else
}
printf ("hexchars == hexchars2\n");
8
278 Chapter 8. Library Reference
memcpy
Summary: #include <string.h>
void *memcpy (
void *dest, /* destination buffer */
void *src, /* source buffer */
int len); /* maximum bytes to copy */
Description: The memcpy function copies len bytes from src to dest.
If these memory buffers overlap, the memcpy function
cannot guarantee that bytes in src are copied to dest
before being overwritten. If these buffers do overlap, use
the memmove function.
char *p;
8
Keil Software — Cx51 Compiler User’s Guide 279
memmove
Summary: #include <string.h>
void *memmove (
void *dest, /* destination buffer */
void *src, /* source buffer */
int len); /* maximum bytes to move */
8
280 Chapter 8. Library Reference
memset
Summary: #include <string.h>
void *memset (
void *buf, /* buffer to initialize */
char c, /* byte value to set */
int len); /* buffer length */
Description: The memset function sets the first len bytes in buf to c.
8
Keil Software — Cx51 Compiler User’s Guide 281
modf
Summary: #include <math.h>
float modf (
float val, /* value to calculate modulo for */
float *ip); /* integer portion of modulo */
Description: The modf function splits the floating-point number val into
integer and fractional components. The fractional part of
val is returned as a signed floating-point number. The
integer part is stored as a floating-point number at ip.
Return Value: The modf function returns the signed fractional part of val.
x = 123.456;
8
282 Chapter 8. Library Reference
_nop_
Summary: #include <intrins.h>
void _nop_ (void);
Description: The _nop_ routine inserts an 8051 NOP instruction into the
program. This routine can be used to pause for 1 CPU
cycle. This routine is implemented as an intrinsic function.
The code required is included in-line rather than being
called.
P1 = 0xFF;
P1 = 0x00;
8
Keil Software — Cx51 Compiler User’s Guide 283
offsetof
Summary: #include <stddef.h>
int offsetof (
structure, /* structure to use */
member); /* member to get offset for */
Return Value: The offsetof macro returns the offset, in bytes, of the
member element from the beginning of struct structure.
struct index_st
{
unsigned char type;
unsigned long num;
unsigned ing len;
};
8
284 Chapter 8. Library Reference
pow
Summary: #include <math.h>
float pow (
float x, /* value to use for base */
float y); /* value to use for exponent */
Return Value: The pow function returns the value xy. If x ≠ 0 and y = 0,
pow returns a value of 1. If x = 0 and y ≤ 0, pow returns
NaN. If x < 0 and y is not an integer, pow returns NaN.
base = 2.0;
power = 8.0;
8
Keil Software — Cx51 Compiler User’s Guide 285
printf / printf517
Summary: #include <stdio.h>
int printf (
const char *fmtstr /* format string */
, arguments…); /* additional arguments */
The format string is read from left to right. The first format
specification encountered references the first argument after
fmtstr and converts and outputs it using the format
specification. The second format specification accesses the
second argument after fmtstr, and so on. If there are more
arguments than format specifications, the extra arguments
are ignored. Results are unpredictable if there are not
enough arguments for the format specifications.
8
286 Chapter 8. Library Reference
8
Keil Software — Cx51 Compiler User’s Guide 287
Flag Meaning
- Left justify the output in the specified field width.
+ Prefix the output value with a + or - sign if the output is a
signed type.
blank (‘ ’) Prefix the output value with a blank if it is a signed positive
value. Otherwise, no blank is prefixed.
# Prefixes a non-zero output value with 0, 0x, or 0X when
used with o, x, and X field types, respectively.
8
288 Chapter 8. Library Reference
8
Keil Software — Cx51 Compiler User’s Guide 289
NOTE
This function is implementation-specific and is based on the
operation of the putchar function. This function, as
provided in the standard library, writes characters using the
serial port of the 8051. Custom functions may use other I/O
devices.
You must ensure that the argument type matches that of the
format specification. You can use type casts to ensure that
the proper type is passed to printf.
8
290 Chapter 8. Library Reference
a = 1;
b = 12365;
c = 0x7FFFFFFF;
x = 'A';
y = 54321;
z = 0x4A6F6E00;
f = 10.0;
g = 22.95;
8
Keil Software — Cx51 Compiler User’s Guide 291
putchar
Summary: #include <stdio.h>
char putchar (
char c); /* character to output */
NOTE
This routine is implementation-specific and its function may
deviate from that described above. Source is included for
the _getkey and putchar functions which may be modified to
provide character level I/O for any hardware device. Refer
to “Customization Files” on page 143 for more information.
8
292 Chapter 8. Library Reference
puts
Summary: #include <stdio.h>
int puts (
const char *string); /* string to output */
NOTE
This function is implementation-specific and is based on the
operation of the putchar function. This function, as
provided in the standard library, writes characters using the
serial port of the 8051. Custom functions may use other I/O
devices.
Return Value: The puts function returns EOF if an error occurred and a
value of 0 if no errors were encountered.
8
Keil Software — Cx51 Compiler User’s Guide 293
rand
Summary: #include <stdlib.h>
int rand (void);
8
294 Chapter 8. Library Reference
realloc
Summary: #include <stdlib.h>
void *realloc (
void xdata *p, /* previously allocated block */
unsigned int size); /* new size for block */
NOTE
Source code is provided for this routine in the folder
\KEIL\C51\LIB. You can modify the source to customize this
function for your hardware environment. Refer to
“Chapter 6. Advanced Programming Techniques” on page
143 for more information.
Return Value: The realloc function returns a pointer to the new block. If
there is not enough memory in the memory pool to satisfy
the memory request, a null pointer is returned and the
original memory block is not affected.
p = malloc (100);
if (p != NULL) {
new_p = realloc (p, 200);
8 }
}
else printf ("Reallocation failed\n");
Keil Software — Cx51 Compiler User’s Guide 295
scanf
Summary: #include <stdio.h>
int scanf (
const char *fmtstr /* format string */
, argument…); /* additional arguments */
Description: The scanf function reads data using the getchar routine.
Data input are stored in the locations specified by argument
according to the format string fmtstr. Each argument must
be a pointer to a variable that corresponds to the type
defined in fmtstr which controls the interpretation of the
input data. The fmtstr argument is composed of one or
more whitespace characters, non-whitespace characters, and
format specifications as defined below.
Values in the input stream are called input fields and are
delimited by whitespace characters. When converting input
fields, scanf ends a conversion for an argument when a
whitespace character is encountered. Additionally, any
unrecognized character for the current format specification
ends a field conversion.
8 Character
d
Argument Type
int *
Input Format
Signed decimal number
i int * Signed decimal, hexadecimal, or
octal integer
u unsigned int * Unsigned decimal number
Keil Software — Cx51 Compiler User’s Guide 297
NOTE
This function is implementation-specific and is based on the
operation of the _getkey and/or putchar functions. These
functions, as provided in the standard library, read and
write characters using the serial port of the 8051. Custom
functions may use other I/O devices.
Return Value: The scanf function returns the number of input fields that
were successfully converted. An EOF is returned if an error
is encountered.
unsigned char x;
unsigned int y;
unsigned long z;
float f,g;
int argsread;
8
Keil Software — Cx51 Compiler User’s Guide 299
setjmp
Summary: #include <setjmp.h>
int setjmp (
jmp_buf env); /* current environment */
Description: The setjmp function saves the current state of the CPU in
env. The state can be restored by a subsequent call to the
longjmp function. When used together, the setjmp and
longjmp functions provide you with a way to execute a
non-local goto.
Return Value: The setjmp function returns a value of 0 when the current
state of the CPU has been copied to env. A non-zero value
indicates that the longjmp function was executed to return
to the setjmp function call. In such a case, the return value
is the value passed to the longjmp function.
8
300 Chapter 8. Library Reference
sin / sin517
Summary: #include <math.h>
float sin (
float x); /* value to calculate
sine for */
8
Keil Software — Cx51 Compiler User’s Guide 301
sinh
Summary: #include <math.h>
float sinh (
float val); /* value to calc hyperbolic sine for */
8
302 Chapter 8. Library Reference
sprintf / sprintf517
Summary: #include <stdio.h>
int sprintf (
char *buffer, /* storage buffer */
const char *fmtstr /* format string */
, argument…); /* additional arguments */
NOTE
The total number of bytes that may be passed to sprintf is
limited due to the memory restrictions imposed by the 8051.
A maximum of 15 bytes may be passed in small model or
compact model. A maximum of 40 bytes may be passed in
large model.
8
Keil Software — Cx51 Compiler User’s Guide 303
int a,b;
float pi;
a = 123;
b = 456;
pi = 3.14159;
8
304 Chapter 8. Library Reference
sqrt / sqrt517
Summary: #include <math.h>
float sqrt (
float x); /* value to calculate square root
of */
Return Value: The sqrt function returns the positive square root of x.
x = 25.0;
y = sqrt (x); /* y = 5 */
8
Keil Software — Cx51 Compiler User’s Guide 305
srand
Summary: #include <stdlib.h>
void srand (
int seed); /* random number generator seed */
Description: The srand function sets the starting value seed used by the
pseudo-random number generator in the rand function. The
random number generator produces the same sequence of
pseudo-random numbers for any given value of seed.
srand (56);
8
306 Chapter 8. Library Reference
sscanf / sscanf517
Summary: #include <stdio.h>
int sscanf (
char *buffer, /* scanf input buffer */
const char *fmtstr /* format string */
, argument…); /* additional arguments */
Description: The sscanf function reads data from the string buffer. Data
input are stored in the locations specified by argument
according to the format string fmtstr. Each argument must
be a pointer to a variable that corresponds to the type
defined in fmtstr which controls the interpretation of the
input data. The fmtstr argument is composed of one or
more whitespace characters, non-whitespace characters, and
format specifications, as defined in the scanf function
description. Refer to “scanf” on page 295 for a complete
description of the formation string and additional arguments.
NOTE
The total number of bytes that may be passed to sscanf is
limited due to the memory restrictions imposed by the 8051.
A maximum of 15 bytes may be passed in small model or
compact model. A maximum of 40 bytes may be passed in
large model.
Return Value: The sscanf function returns the number of input fields that
were successfully converted. An EOF is returned if an error
is encountered.
unsigned char x;
unsigned int y;
unsigned long z;
float f,g;
int argsread;
8
308 Chapter 8. Library Reference
strcat
Summary: #include <string.h>
char *strcat (
char *dest, /* destination string */
char *src); /* source string */
8
Keil Software — Cx51 Compiler User’s Guide 309
strchr
Summary: #include <string.h>
char *strchr (
const char *string, /* string to search */
char c); /* character to find */
Description: The strchr function searches string for the first occurrence
of c. The null character terminating string is included in
the search.
if (s != NULL)
printf ("found a 't' at %s\n", s);
}
8
310 Chapter 8. Library Reference
strcmp
Summary: #include <string.h>
char strcmp (
char *string1, /* first string */
char *string2); /* second string */
Return Value: The strcmp function returns the following values to indicate
the relationship of string1 to string2:
Value Meaning
<0 string1 less than string2
=0 string1 equal to string2
>0 string1 greater than string2
if (i < 0)
printf ("buf1 < buf2\n");
else if (i > 0)
printf ("buf1 > buf2\n");
else
printf ("buf1 == buf2\n");
}
8
Keil Software — Cx51 Compiler User’s Guide 311
strcpy
Summary: #include <string.h>
char *strcpy (
char *dest, /* destination string */
char *src); /* source string */
Description: The strcpy function copies src to dest and appends a null
character to the end of dest.
8
312 Chapter 8. Library Reference
strcspn
Summary: #include <string.h>
int strcspn (
char *src, /* source string */
char *set); /* characters to find */
Description: The strcspn function searches the src string for any of the
characters in the set string.
Return Value: The strcspn function returns the index of the first character
located in src that matches a character in set. If the first
character in src matches a character in set, a value of 0 is
returned. If there are no matching characters in src, the
length of the string is returned.
8
Keil Software — Cx51 Compiler User’s Guide 313
strlen
Summary: #include <string.h>
int strlen (
char *src); /* source string */
8
314 Chapter 8. Library Reference
strncat
Summary: #include <string.h>
char *strncat (
char *dest, /* destination string */
char *src, /* source string */
int len); /* max. chars to concatenate */
8
Keil Software — Cx51 Compiler User’s Guide 315
strncmp
Summary: #include <string.h>
char strncmp (
char *string1, /* first string */
char *string2, /* second string */
int len); /* max characters to
compare */
Value Meaning
<0 string1 less than string2
=0 string1 equal to string2
>0 string1 greater than string2
char i;
8
316 Chapter 8. Library Reference
strncpy
Summary: #include <string.h>
char *strncpy (
char *dest, /* destination string */
char *src, /* source string */
int len); /* max characters to
copy */
8
Keil Software — Cx51 Compiler User’s Guide 317
strpbrk
Summary: #include <string.h>
char *strpbrk (
char *string, /* string to search */
char *set); /* characters to find */
char *p;
if (p == NULL)
printf ("No vowels found in %s\n", text);
else
printf ("Found a vowel at %s\n", p);
8
318 Chapter 8. Library Reference
strpos
Summary: #include <string.h>
int strpos (
const char *string, /* string to search */
char c); /* character to find */
Description: The strpos function searches string for the first occurrence
of c. The null character terminating string is included in
the search.
Return Value: The strpos function returns the index of the character
matching c in string or a value of -1 if no matching
character was found. The index of the first character in
string is 0.
int i;
if (i == -1)
printf ("No spaces found in %s\n", text);
else
printf ("Found a space at offset %d\n", i);
8
Keil Software — Cx51 Compiler User’s Guide 319
strrchr
Summary: #include <string.h>
char *strrchr (
const char *string, /* string to search */
char c); /* character to find */
Description: The strrchr function searches string for the last occurrence
of c. The null character terminating string is included in
the search.
Return Value: The strrchr function returns a pointer to the last character c
found in string or a null pointer if no matching character
was found.
if (s != NULL)
printf ("found the last 't' at %s\n", s);
8
320 Chapter 8. Library Reference
strrpbrk
Summary: #include <string.h>
char *strrpbrk (
char *string, /* string to search */
char *set); /* characters to find */
Return Value: The strrpbrk function returns a pointer to the last matching
character in string. If string contains no characters from
set, a null pointer is returned.
char *p;
if (p == NULL)
printf ("No vowels found in %s\n", text);
else
printf ("Last vowel is at %s\n", p);
8
Keil Software — Cx51 Compiler User’s Guide 321
strrpos
Summary: #include <string.h>
int strrpos (
const char *string, /* string to search */
char c); /* character to find */
Description: The strrpos function searches string for the last occurrence
of c. The null character terminating string is included in
the search.
Return Value: The strrpos function returns the index of the last character
matching c in string or a value of -1 if no matching
character was found. The index of the first character in
string is 0.
int i;
if (i == -1)
printf ("No spaces found in %s\n", s);
else
printf ("Last space in %s is at offset %d\n",
s, i);
}
8
322 Chapter 8. Library Reference
strspn
Summary: #include <string.h>
int strspn (
char *string, /* string to search */
char *set); /* characters to allow */
Description: The strspn function searches the src string for characters
not found in the set string.
Return Value: The strspn function returns the index of the first character
located in src that does not match a character in set. If the
first character in src does not match a character in set, a
value of 0 is returned. If all characters in src are found in
set, the length of src is returned.
8
Keil Software — Cx51 Compiler User’s Guide 323
strtod / strtod517
Summary: #include <stdlib.h>
unsigned long strtod (
const char *string, /* string to convert */
char **ptr); /* ptr to subsequent characters */
Return Value: The strtod function returns the floating-point value that is
produced by interpreting the characters in string as a
number.
8
Keil Software — Cx51 Compiler User’s Guide 325
strtol
Summary: #include <stdlib.h>
long strtol (
const char *string, /* string to convert */
char **ptr, /* ptr to subsequent characters */
unsigned char base);/* number base for conversion */
Description: The strtol function converts string into a long value. The
input string is a sequence of characters that can be
interpreted as an integer number. Whitespace characters at
the beginning of string are skipped. An optional sign may
precede the number.
where:
char s [] = "-123456789";
8
Keil Software — Cx51 Compiler User’s Guide 327
strtoul
Summary: #include <stdlib.h>
unsigned long strtoul (
const char *string, /* string to convert */
char **ptr, /* ptr to subsequent characters */
unsigned char base);/* number base for conversion */
where:
char s [] = "12345AB";
8
Keil Software — Cx51 Compiler User’s Guide 329
tan / tan517
Summary: #include <math.h>
float tan (
float x); /* value to calculate tangent of
*/
pi = 3.14159;
8
330 Chapter 8. Library Reference
tanh
Summary: #include <math.h>
float tanh (
float x); /* value to calc hyperbolic
tangent for */
Description: The tanh function calculates the hyperbolic tangent for the
floating-point value x.
pi = 3.14159;
8
Keil Software — Cx51 Compiler User’s Guide 331
_testbit_
Summary: #include <intrins.h>
bit _testbit_ (
bit b); * bit to test and clear */
if (_testbit_ (test_flag))
printf ("Bit was set\n");
else
printf ("Bit was clear\n");
}
8
332 Chapter 8. Library Reference
toascii
Summary: #include <ctype.h>
char toascii (
char c); /* character to convert */
Return Value: The toascii macro returns the 7-bit ASCII character for c.
k = toascii (c);
8
Keil Software — Cx51 Compiler User’s Guide 333
toint
Summary: #include <ctype.h>
char toint (
char c); /* digit to convert */
Return Value: The toint function returns the value of the ASCII
hexadecimal character c.
l += toint (k);
}
}
8
334 Chapter 8. Library Reference
tolower
Summary: #include <ctype.h>
char tolower (
char c); /* character to convert */
8
Keil Software — Cx51 Compiler User’s Guide 335
_tolower
Summary: #include <ctype.h>
char _tolower (
char c); /* character to convert */
8
336 Chapter 8. Library Reference
toupper
Summary: #include <ctype.h>
char toupper (
char c); /* character to convert */
8
Keil Software — Cx51 Compiler User’s Guide 337
_toupper
Summary: #include <ctype.h>
char _toupper (
char c); /* character to convert */
8
338 Chapter 8. Library Reference
ungetchar
Summary: #include <stdio.h>
char ungetchar (
char c); /* character to unget */
Description: The ungetchar function stores the character c back into the
input stream. Subsequent calls to getchar and other stream
input functions return c. Only one character may be passed
to unget between calls to getchar.
8
Keil Software — Cx51 Compiler User’s Guide 339
va_arg
Summary: #include <stdarg.h>
type va_arg (
argptr, /* optional argument list */
type); /* type of next argument */
The first call to va_arg returns the first argument after the
prevparm argument specified in the va_start macro.
Subsequent calls to va_arg return the remaining arguments
in succession.
Return Value: The va_arg macro returns the value for the specified
argument type.
8
340 Chapter 8. Library Reference
if (id == 0) {
int arg1;
char *arg2;
long arg3;
8
Keil Software — Cx51 Compiler User’s Guide 341
va_end
Summary: #include <stdarg.h>
void va_end (
argptr); /* optional argument list */
8
342 Chapter 8. Library Reference
va_start
Summary: #include <stdarg.h>
void va_start (
argptr, /* optional argument list */
prevparm); /* arg preceding optional args */
8
Keil Software — Cx51 Compiler User’s Guide 343
vprintf
Summary: #include <stdio.h>
void vprintf (
const char * fmtstr, /* pointer to format string */
char * argptr); /* pointer to argument list */
NOTE
This function is implementation-specific and is based on the
operation of the putchar function. This function, as
provided in the standard library, writes characters using the
serial port of the 8051. Custom functions may use other I/O
devices.
8
344 Chapter 8. Library Reference
8
Keil Software — Cx51 Compiler User’s Guide 345
vsprintf
Summary: #include <stdio.h>
void vsprintf (
char *buffer, /* pointer to storage buffer */
const char * fmtstr, /* pointer to format string */
char * argptr); /* pointer to argument list */
8
346 Chapter 8. Library Reference
8
Keil Software — Cx51 Compiler User’s Guide 347
Compiler-related Differences
Wide Characters
Wide 16-bit characters are not supported by Cx51. ANSI provides wide
characters for future support of an international character set.
Recursive Function Calls
Recursive function calls are not supported by default. Functions that are
recursive must be declared using the reentrant function attribute. Reentrant
functions can be called recursively because the local data and parameters are
stored in a reentrant stack. In comparison, functions which are not declared
using the reentrant attribute use static memory segments for the local data of
the function. A recursive call to these functions overwrites the local data of
the prior function call instance.
Library-related Differences
The ANSI C Standard Library includes a vast number of routines, most of which
are included in Cx51. Many, however, are not applicable to an embedded
application and are excluded from the Cx51 library.
The following ANSI Standard library routines are included in the Cx51 library:
The following ANSI Standard library routines are not included in the Cx51
library:
The following routines are not found in the ANSI Standard Library but are
included in the Cx51 library.
acos517
asin517
_irol_
_iror_
sscanf517
strpos
A
atan517 log10517 strrpbrk
atof517 log517 strrpos
strtod517 _lrol_ tan517
cabs _lror_ _testbit_
_chkfloat_ memccpy toascii
cos517 _nop_ toint
_crol_ printf517 _tolower
_cror_ scanf517 _toupper
exp517 sin517 ungetchar
_getkey sprintf517
init_mempool sqrt517
350 Appendix A. Differences from ANSI C
A
Keil Software — Cx51 Compiler User’s Guide 351
NOTE
Support for the OMF2 output file format, Philips 80C51MX, Dallas Contigouos
Mode, and VARBANKING requires the PK51 Professional Developers Kit.
These options cannot be used in the CA51 and DK51 packages.
Version 5 Differences
Optimize Level 7, 8, and 9
C51 offers three new optimizer levels. These new optimizations focus
primarily on code density. Refer to “Optimizer” on page 155 for more
information.
352 Appendix B. Version Differences
B 5 did not overlay pdata or xdata variables if a function where compiled in the
SMALL memory model.
The data type enum adjusts automatically 8 or 16 bits.
C51 now uses a char variable to represent an enum, if the enum range allows
that.
modf, strtod, strtol, strtoul Library Functions
C51 includes now the ANSI standard library functions modf, strtod, strtol,
strtou
Directives BROWSE, INCDIR, ONEREGBANK, RET_XSTK,
RET_PSTK
C51 supports new directives for generating Browse Information, specifing
include directives, optimizing interrupt code, and using the reentrant stack for
return addresses. Refer to “Chapter 2. Compiling with Cx51” on page 19 for
more information.
Version 4 Differences
Byte Order of Floating-point Numbers
Floating-point numbers are now stored in the big endian order. Previous
releases of the C51 compiler stored floating-point numbers in little endian
format. Refer to “Floating-point Numbers” on page 177 for more
information.
_chkfloat_ Library Function
The intrinsic function _chkfloat_ allows for fast testing of floating-point
numbers for error (NaN), ±INF, zero and normal numbers. Refer to
“_chkfloat_” on page 240 for more information.
FLOATFUZZY Directive
C51 now supports the FLOATFUZZY directive. This directive controls the
number of bits ignored during the execution of a floating-point compare.
Refer to “FLOATFUZZY” on page 40 for more information.
Floating-point Arithmetic is Fully Reentrant
Intrinsic floating-point arithmetic operations (add, subtract, multiply, divide,
Keil Software — Cx51 Compiler User’s Guide 353
and compare) are now fully reentrant. The C library routines fpsave and
fprestore are no longer needed. Several library routines are also reentrant.
Refer to “Routines by Category” on page 212 for more information.
Long and Floating-point Operations no Longer use an Arithmetic Stack
The long and floating-point arithmetic is more efficient; the code generated
is now totally register-based and does not use a simulated arithmetic stack.
This also reduces the memory needs of the generated code.
Memory Types
The memory types have been changed to achieve better performance in the
B
run-time library and to reflect the memory map of the MCS® 251 architecture.
Memory Type Bytes for Generic Pointers
The memory type bytes used in generic pointers have changed. The
following table contains the memory type byte values and their associated
memory type.
Memory Type idata data bdata xdata pdata code
C51 V5 Value 0x00 0x00 0x00 0x01 0xFE 0xFF
C51 V4 Value 0x01 0x04 0x04 0x02 0x03 0x05
WARNINGLEVEL Directive
C51 now supports the WARNINGLEVEL directive which lets you specify
the strength of the warning detection for the C51 compiler. The C51
compiler now also checks for unused local variables, labels, and expressions.
Refer to “VARBANKING
Abbreviation: VB
Arguments: None.
NOTE
For extended 8051 devices and variable banking with
classic 8051 devices several Keil Application Notes will
become available on www.keil.com or the Keil development
354 Appendix B. Version Differences
#pragma VARBANKING
There is a big difference between 8-bit and 16-bit operations on the 8-bit
8051 in terms of code size and execution speed. For this reason, you might
want to disable integer promotion by using the NOINTPROMOTE control
directive.
Trigraphs
C51 now supports trigraph sequences.
Variable-length Argument Lists for All Functions
Variable-length argument lists are now supported for all function types.
Functions with a variable length argument list do not have to be declared
using the reentrant attribute. The new command line directive MAXARGS
determines the size of the parameter passing area.
Version 2 Differences
Absolute Register Addressing
C51 now generates code that performs absolute register addressing. This
improves execution speed. The control directives AREGS and NOAREGS,
respectively, enable or disable this feature.
Bit-addressable Memory Type
B Variable types of char and int can now be declared to reside in the
bit-addressable internal memory area by using the bdata memory specifier.
Intrinsic Functions
Intrinsic functions have been added to the library to support some of the
special instructions built in to the 8051.
Mixed Memory Models
Calls to and from functions of different memory models are now supported.
New Optimizer Levels
Two new levels of optimization have been added to the C51 compiler. These
new levels support register variables, local common subexpression
elimination, loop optimizations, and global common subexpression
elimination, to name a few.
New Predefined Macros
The macros _ _C51_ _ and _ _MODEL_ _ are now defined by the
preprocessor at compile time.
Reentrant and Recursive Functions
Individual functions may now be defined as being reentrant or recursive by
using the reentrant function attribute.
Registers Used for Parameter Passing
C51 now passes up to 3 function arguments using registers. The
REGPARMS and NOREGPARMS directives enable or disable this feature.
Support for Memory-specific Pointers
Pointers may now be defined to reference data in a particular memory area.
Support for PL/M-51 Functions
The alien keyword has been added to support PL/M-51 compatible functions
and function calls.
Volatile Type Specifier
The volatile variable attribute may be used to enforce variable access and to
prevent optimizations involving that variable.
Keil Software — Cx51 Compiler User’s Guide 359
or
If you are using old debugging tools, you may have problems displaying
floating-point numbers and pointers. Make sure that you have current versions
of the debugging software.
Keil Software — Cx51 Compiler User’s Guide 361
Memory Model
The most significant impact on code size and execution speed is memory model.
Compiling in small model always generates the smallest, fastest code possible.
The SMALL control directive instructs the Cx51 compiler to use the small
memory model. In small model, all variables, unless declared otherwise, reside
C
in the internal memory of the 8051. Memory access to internal data memory is
fast (typically performed in 1 or 2 clock cycles), and the generated code is much
smaller than that generated with the compact or large models. For example, the
following loop:
for (i = 0; i < 100; i++) {
do_nothing ();
}
is compiled both in small model and in large model to demonstrate the difference
in generated code. The following is the small model translation:
stmt level source
1 #pragma small
2
3 void do_nothing (void);
4
5
6 void func (void)
7 {
8 1 unsigned char i;
9 1
10 1 for (i = 0; i < 100; i++)
11 1 {
12 2 do_nothing ();
13 2 }
14 1 }
; FUNCTION func (BEGIN)
; SOURCE LINE # 10
0000 E4 CLR A
0001 F500 R MOV i,A
0003 ?C0001:
0003 E500 R MOV A,i
0005 C3 CLR C
0006 9464 SUBB A,#064H
362 Appendix C. Writing Optimum Code
Variable Location
Frequently accessed data objects should be located in the internal data memory
of the 8051. Accessing the internal data memory is much more efficient than
accessing the external data memory. The internal data memory is shared among
register banks, the bit data area, the stack, and other user defined variables with
the memory type data.
Because of the limited amount of internal data memory (128 to 256 bytes), all
your program variables may not fit into this memory area. In this case, you must
locate some variables in other memory areas. There are two ways to do this.
One way is to change the memory model and let the compiler do all the work.
This is the simplest method, but it is also the most costly in terms of the amount C
of generated code and system performance. Refer to “Memory Model” on page
361 for more information.
Another way to locate variables in other memory areas is to manually select the
variables that can be moved into external data memory and declare them using
the xdata memory specifier. Usually, string buffers and other large arrays can
be declared with the xdata memory type without a significant degradation in
performance or increase in code size.
Variable Size
Members of the 8051 family are all 8-bit CPUs. Operations that use 8-bit types
(like char and unsigned char) are much more efficient than operations that use
int or long types. For this reason, always use the smallest data type possible.
The Cx51 compiler directly supports all byte operations. Byte types are not
promoted to integers unless required. See the INTPROMOTE directive for
more information.
Unsigned Types
The 8051 family of processors does not specifically support operations with
signed numbers. The compiler must generate additional code to deal with sign
extensions. Far less code is produced if unsigned objects are used wherever
possible.
Local Variables
When possible, use local variables for loops and other temporary calculations.
As part of the optimization process, the compiler attempts to maintain local
C variables in registers. Register access is the fastest type of memory access. The
best effect is normally achieved with unsigned char and unsigned int variable
types.
Other Sources
The quality of the compiler generated code is more often than not directly
influenced by the algorithms implemented in the program. Sometimes, you can
improve the performance or reduce the code size simply by using a different
algorithm. For example, a heap sort algorithm always outperforms a bubble sort
algorithm.
For more information on how to write efficient programs, refer to the following
books:
Efficient C
Plum & Brodie
Plum Hall, Inc.
ISBN 0-911537-05-8
Keil Software — Cx51 Compiler User’s Guide 365
For the most part, there are no limits placed on the compiler with respect to
components of the C language; for example, you may specify an unlimited
number of symbols or number of case statements in a switch block. If there is
enough address space, several thousand symbols could be defined. However if
you are using the Intel OMF51 file format, C51 is bound by a historical limit of
256 global symbols.
NOTE
This limits do not apply if you are using the OMF2 file format or the CX51
compiler.
Keil Software — Cx51 Compiler User’s Guide 367
When using data that are stored in multiple bytes, byte ordering becomes an
issue. Unfortunately, there is not just one standard for the order in which bytes
in multi-byte data are stored. There are two popular methods of byte ordering
currently in widespread use.
The first method is called little endian and is often referred to as Intel order. In
little endian, the least significant, or low-order byte is stored first. For example,
a 16-bit integer value of 0x1234 (4660 decimal) would be stored using the little
endian method in two consecutive bytes as follows:
Address +0 +1
Contents 0x34 0x12
A second method of accessing multi-byte data is called big endian and is often
referred to as Motorola order. In big endian, the most significant, or high-order
byte is stored first, and the least significant, or low-order byte is stored last. For
example, a 16-bit integer value of 0x1234 would be stored using the big endian
method in two consecutive bytes as follows:
Address +0 +1
Contents 0x12 0x34
A 32-bit integer value of 0x004A4F4E would be stored using the big endian
method as follows:
Address +0 +1 +2 +3
Contents 0x00 0x4A 0x4F 0x4E
368 Appendix E. Byte Ordering
The 8051 is an 8-bit machine and has no instructions for directly manipulating
data objects that are larger than 8 bits. Multi-byte data are stored according to
the following rules.
The 8051 LCALL instruction stores the address of the next instruction on the
stack. The address is pushed onto the stack low-order byte first. The address
is, therefore, stored in memory in little endian format.
All other 16-bit and 32-bit values are stored, contrary to other Intel
processors, in big endian format, with the high-order byte stored first. For
example, the LJMP and LCALL instructions expect 16-bit addresses that are
in big endian format.
Floating-point numbers are stored according to the IEEE-754 format and are
stored in big endian format with the high-order byte stored first.
E
Keil Software — Cx51 Compiler User’s Guide 369
BL51 EXAMPLE1.OBJ IX F
fails and display the following error message.
*** WARNING 13: RECURSIVE CALL TO SEGMENT
SEGMENT: ?CO?EXAMPLE1
CALLER: ?PR?FUNC2?EXAMPLE1
?CO?EXAMPLE1 ~ FUNC2 deletes the implied call reference between func2 and
the code constant segment in the example. Then, MAIN ! FUNC2 adds an
additional call to the reference listing between MAIN and FUNC2 instead. Refer
to the 8051 Utilities User’s Guide for more information.
does not print the string “A 1 2 3”. This is because the Cx51 compiler passes the
arguments 1, 2, and 3 all as 8-bit byte types. The format specifiers %d and
%u both expect 16-bit int types.
F To avoid this type of problem, you must explicitly define the data type to pass to
the printf function. To do this, you must type cast the above values. For
example:
printf ("%c %d %u %bu", 'A',(int) 1, (unsigned int) 2, (char) 3);
If you are uncertain of the size of the argument that is passed, you may cast the
value to the desired size.
Keil Software — Cx51 Compiler User’s Guide 371
Uncalled Functions
It is common practice during the development process to write but not call
additional functions. While the compiler permits this without error, the
Linker/Locator does not treat this code casually, because of the support for data
overlaying, and emits a warning message.
Interrupt functions are never called, they are invoked by the hardware. An
uncalled routine is treated as a potential interrupt routine by the linker. This
means that the function is assigned non-overlayable data space for its local
variables. This quickly exhausts all available data memory (depending upon the
memory model used).
If you unexpectedly run out of memory, be sure to check for linker warnings
relating to uncalled or unused routines. You can use the linker’s IXREF control
directive to include a cross reference list in the linker map (.M51) file.
F
372 Appendix F. Hints, Tips, and Techniques
In order to generate the appropriate instructions, the compiler must have the
absolute value of the reference to be generated. In the above example, this
cannot be done, as this address of xyz_flag cannot be known until after the
linking phase has been completed. Follow the rules below to avoid this problem.
1. A bdata variable (defined and used in the same way as an sfr) must be
defined in global space; not within the scope of a procedure.
2. A bdata bit variable (defined and used in the same way as an sbit) must also
be defined in global space, and cannot be located within the scope of a
procedure.
3. The definition of the bdata variable and the creation of its sbit access
component name must be accomplished where the compiler has a “view” of
both the variable and the component.
For example, declare the bdata variable and the bit component in the same
F source module:
bdata char xyz_flag;
sbit xyz_bit1 = xyz_flag^1;
As with any other declared and named C variable that reserves space, simply
define your bdata variable and its component sbits in a module. Then, use the
extern bit specifier to reference it as the need arises.
Keil Software — Cx51 Compiler User’s Guide 373
Using Monitor-51
If you want to test a C program with Monitor-51 and if the Monitor-51 is
installed at code address 0, consider the following rules (the specification refers
to a target system where the available code memory for user programs starts at
address 8000H):
All C modules which contain interrupt functions must be translated with the
control directive INTVECTOR (0x8000).
In the file STARTUP.A51 (directory: LIB) the statement CSEG AT 0 must be
replaced with CSEG AT 8000H. The this file must be assembled and added
to the linker/locator invocation according the specifications in the file header.
F
374 Appendix F. Hints, Tips, and Techniques
Function Pointers
Function pointers are one of the most difficult aspects of C to understand and to
properly utilize. Most problems involving function pointers are caused by
improper declaration of the function pointer, improper assignment, and improper
dereferencing.
The following brief example demonstrates how to declare a function pointer (f),
how to assign function addresses to it, and how to call the functions through the
pointer. The printf routine is used for example purposes when running DS51 to
simulate program execution.
#pragma code symbols debug oe
void main(void) {
void (*f)(int i); /* Declaration of a function pointer */
/* that takes one integer arguments */
/* and returns nothing */
F TR1
TI
= 1;
= 1; /* TI:
/* TR1: timer 1 run
set TI to send first char of UART
*/
*/
while( 1 ) {
f = (void *)func1; /* f points to function #1 */
f(1);
f = (void *)func2; /* f points to function #2 */
f(2);
}
}
NOTE
Because of the limited stack space of the 8051, the linker overlays function
variables and arguments in memory. When you use a function pointer, the linker
cannot correctly create a call tree for your program. For this reason, you may
have to correct the call tree for the data overlaying. Use the OVERLAY
directive with the linker to do this. Refer to the 8051 Utilities User’s Guide for
more information.
Keil Software — Cx51 Compiler User’s Guide 375
Glossary
A51
The standard 8051 Macro Assembler.
AX51
The extended 8051 Macro Assembler.
ANSI
American National Standards Institute. The organization responsible for
defining the C language standard.
argument
The value that is passed to a macro or function.
arithmetic types
Data types that are integral, floating-point, or enumerations.
array
A set of elements, all of the same data type.
ASCII
American Standard Code for Information Interchange. This is a set of 256
codes used by computers to represent digits, characters, punctuation, and
other special symbols. The first 128 characters are standardized. The
remaining 128 are defined by the implementation.
batch file
An ASCII text file containing commands and programs that can be invoked
from the command line.
BL51
The standard 8051 linker/locator.
block
A sequence of C statements, including definitions and declarations, enclosed
within braces ({ }).
376 Glossary
C51
The Optimizing C Compiler for classic 8051 and extended 8051 devices.
CX51
The Optimizing C Compiler for Philips 80C51MX architecture.
constant expression
Any expression that evaluates to a constant non-variable value. Constants
may include character and integer constant values.
control
Command line control switch to the compiler, assembler or linker.
declaration
A C construct that associates the attributes of a variable, type, or function
with a name.
definition
A C construct that specifies the name, formal parameters, body, and return
type of a function or that initializes and allocates storage for a variable.
directive
Instruction or control switch to the compiler, assembler or linker.
escape sequence
A backslash (‘\’) character followed by a single letter or a combination of
digits that specifies a particular character value in strings and character
constants.
expression
A combination of any number of operators and operands that produces a
constant value.
formal parameters
The variables that receive the value of arguments passed to a function.
function
A combination of declarations and statements that can be called by name to
perform an operation and/or return a value.
function body
A block containing the declarations and statements that make up a function.
function call
An expression that invokes and possibly passes arguments to a function.
Keil Software — Cx51 Compiler User’s Guide 377
function declaration
A declaration providing the name and return type of a function that is
explicitly defined elsewhere in the program.
function definition
A definition providing the name, formal parameters, return type, declarations,
and statements describing what a function does.
function prototype
A function declaration that includes a list of formal parameters in parentheses
following the function name.
include file
A text file that is incorporated into a source file.
keyword
A reserved word with a predefined meaning for the compiler or assembler.
L51
The old version of the 8051 linker/locator. L51 is replaced with the BL51
linker/locater.
LX51
The extended 8051 linker/locator.
LIB51, LIBX51
The commands to manipulate library files using the Library Manager.
library
A file that stores a number of possibly related object modules. The linker can
extract modules from the library to use in building a target object file.
LSB
Least significant bit or byte.
macro
An identifier that represents a series of keystrokes.
manifest constant
A macro that is defined to have a constant value.
378 Glossary
MCS® 51
The general name applied to the Intel family of 8051 compatible
microprocessors.
memory model
Any of the models that specifies which memory areas are used for function
arguments and local variables.
mnemonic
An ASCII string that represents a machine language opcode in an assembly
language instruction.
MON51
An 8051 program that can be loaded into your target CPU to aid in debugging
and rapid product development through rapid software downloading.
MSB
Most significant bit or byte.
newline character
A character used to mark the end of a line in a text file or the escape sequence
(‘\n’) to represent the newline character.
null character
ASCII character with the value 0 represented as the escape sequence (‘\0’).
null pointer
A pointer that references nothing. A null pointer has the integer value 0.
object
An area of memory that can be examined. Usually used when referring to the
memory area associated with a variable or function.
object file
A file, created by the compiler, that contains the program segment
information and relocatable machine code.
OH51, OHX51
The commands to convert absolute object files into Intel HEX file format.
opcode
Also referred to as operation code. An opcode is the first byte of a machine
code instruction and is usually represented as a 2–digit hexadecimal number.
The opcode indicates the type of machine language instruction and the type
of operation to perform.
Keil Software — Cx51 Compiler User’s Guide 379
operand
A variable or constant that is used in an expression.
operator
A symbol (e.g., +, -, *, /) that specifies how to manipulate the operands of an
expression.
parameter
The value that is passed to a macro or function.
PL/M-51
A high-level programming language introduced by Intel at the beginning of
the 80ths
pointer
A variable containing the address of another variable, function, or memory
area.
pragma
A statement that passes an instruction to the compiler at compile time.
preprocessor
The compiler’s first pass text processor that manipulates the contents of a C
file. The preprocessor defines and expands macros, reads include files, and
passes control directives to the compiler.
relocatable
Object code that can be relocated and is not at a fixed address.
RTX51 Full
An 8051 Real-time Executive that provides a multitasking operating system
kernel and library of routines for its use.
RTX51 Tiny
A limited version of RTX51.
scalar types
In C, integer, enumerated, floating-point, and pointer types.
scope
Sections of a program where an item (function or variable) can be referenced
by name. The scope of an item may be limited to file, function, or block.
8051. This includes the serial port, timers, counters, I/O ports, and other
hardware control registers.
source file
A text file containing C program or assembly program code.
stack
An area of memory, indirectly accessed by a stack pointer, that shrinks and
expands dynamically as items are pushed onto and popped off of the stack.
Items in the stack are removed on a LIFO (last-in first-out) basis.
static
A storage class that, when used with a variable declaration in a function,
causes variables to retain their value after exiting the block or function in
which they are declared.
stream functions
Routines in the library that read and write characters using the input and
output streams.
string
An array of characters that is terminated with a null character (‘\0’).
string literal
A string of characters enclosed within double quotes (“ ”).
structure
A set of elements of possibly different types grouped together under one
name.
structure member
One element of a structure.
token
A fundamental symbol that represents a name or entity in a programming
language.
two’s complement
A binary notation that is used to represent both positive and negative
numbers. Negative values are created by complementing all bits of a positive
value and adding 1.
type
A description of the range of values associated with a variable. For example,
an int type can have any value within its specified range (-32768 to 32767).
Keil Software — Cx51 Compiler User’s Guide 381
type cast
An operation in which an operand of one type is converted to another type by
specifying the desired type, enclosed within parentheses, immediately
preceding the operand.
µVision2
An integrated software development platform that supports the Keil Software
development tools. µVision2 combines Project Management, Source Code
Editing, and Program Debugging in one environment.
whitespace character
Characters used as delimiters in C programs such as space, tab, and newline.
wild card
One of the characters (? or *) that can be used in place of characters in a
filename.
382 Index
Index
_tolower 213,335
# _toupper 213,337
# 130
## 131
+
#define 129 +INF
#elif 129 described 179
#else 129
#endif 129 1
#error 129
#if 129 16-bit Binary Integer Operations 136
#ifdef 129
#ifndef 129 3
#include 129
32-bit Binary Integer Operations 136
#line 129
#pragma 129
#undef 129 8
8051 Derivatives 133
. 8051 Hardware Stack 114
8051 Memory Areas 86
.I files 21
8051 Variants 17
.LST files 21
8051-Specific Optimizations 156
.OBJ files 21
80C320/520 or variants 54
.SRC files 21
80C517 Routines
acos517 221
_ asin517 221
_ _C51_ _ 132,203 atan517 221
_ _DATE_ _ 132,203 atof517 221
_ _FILE_ _ 132,203 cos517 221
_ _LINE_ _ 132,203 exp517 221
_ _MODEL_ _ 132,203 log10517 221
_ _STDC_ _ 132,200,203 log517 221
_ _TIME_ _ 132,200,203 printf517 221
_at_ 99,182,355 scanf517 221
_chkfloat_ 215,240 sin517 221
_crol_ 205,215,243 sprintf517 221
_cror_ 205,215,244 sqrt517 221
_getkey 217,251 sscanf517 221
_irol_ 205,215,254 strtod517 221
_iror_ 205,215,255 tan517 221
_lrol_ 205,215,272 80C517.H 221
_lror_ 205,215,273 80C751.LIB 206
_nop_ 205,220,282 80x8252 or variants 53
_testbit_ 205,220,331
Keil Software — Cx51 Compiler User’s Guide 383
A AREGS 26
Argument lists, variable-length 50,220
A51 argument, defined 375
Interfacing 161 arithmetic types, defined 375
A51, defined 375 array, defined 375
abs 214,228 ASCII, defined 375
ABSACC.H 222 asin 214,230
Absolute Memory Access function timing 137
Macros 208 asin517 230
CBYTE 208 function timing 137
CWORD 208 ASM 28
DBYTE 209 Assembly code in-line 28
DWORD 209 Assembly listing 31
PBYTE 210 Assembly source file generation 78
PWORD 210 assert 231
XBYTE 211 ASSERt.H 223
XWORD 211 atan 214,232
Absolute Memory Locations 180 function timing 137
Absolute register addressing 26 atan2 214,233
Absolute value atan517 232
abs 228 function timing 137
cabs 237 Atmel
fabs 246 89x8252 and variants 134
labs 267 Atmel 80x8252 or variants 53
Abstract Pointers 109 Atmel WM
Access Optimizing 156 dual DPTR support 140
Accessing Absolute Memory atof 214,234
Locations 180 function timing 137
acos 214,229 atof517 234
function timing 137 function timing 137
acos517 229 atoi 214,235
function timing 137 atol 214,236
Additional items, notational AUTOEXEC.BAT 19
conventions 5 AX51, defined 375
Address of interrupts 120
Advanced Programming
Techniques 143 B
alien 127 batch file, defined 375
ANSI bdata 87
Differences 347 bdata, tips for 372
Include Files 221 big endian 367
Library 205 Binary Integer Operations 136
Standard C Constant 132 Binary-Coded Decimal (BCD),
ANSI, defined 375 defined 375
Arc bit
cosine 229 As first parameter in function
sine 230 call 115
tangent 232,233 Bit shifting functions
384 Index
P _ _MODEL_ _ 132
_ _STDC_ _ 132
Page length in listing file 65 _ _TIME_ _ 132
Page width in listing file 66 Preface 3
PAGELENGTH 65 PREPRINT 67
PAGEWIDTH 66 Preprocessor 129
Parameter Passing in Fixed Preprocessor directives
Memory Locations 163 define 129
Parameter Passing in Registers 162 elif 129
Parameter Passing Via Registers 156 else 129
parameter, defined 379 endif 129
Passing arguments in registers 71 error 129
Passing Parameters in Registers 115 if 129
PATH 19 ifdef 129
PBPSTACK 145 ifndef 129
PBPSTACKTOP 145 include 129
PBYTE 180,210 line 129
pdata 88 pragma 129
PDATALEN 144 undef 129
PDATASTART 144 Preprocessor output file
Peephole Optimization 156 generation 67
Philips preprocessor, defined 379
8xC750 139 PRINT 68
8xC751 139 Printed text, notational
8xC752 139 conventions 5
dual DPTR support 140 printf 217,285
Philips dual DPTR 55 printf, tips for 370
PL 65 printf517 285
PL/M-51 127 Program Memory 86
Defined 379 Program memory size 75
Interfacing 173 putchar 217,291
Pointer Conversions 106 PUTCHAR.C 153
Pointers 101 puts 217,292
Generic 101 PW 66
Memory-specific 104 PWORD 180,210
pointers, defined 379
pow 214,284
PP 67 R
PPAGE 145 R0-R7 26
PPAGEENABLE 145 rand 215,293
PR 68 Range for data types 92
pragma 129 RB 70
pragma, defined 379 realloc 216,294
Predefined Macro Constants 132 REALLOC.C 154
_ _C51_ _ 132 Real-Time Function Tasks 128
_ _DATE_ _ 132 Recursive Code, tips for 369
_ _FILE_ _ 132 Recursive Functions 124
_ _LINE_ _ 132 reentrant 124
Keil Software — Cx51 Compiler User’s Guide 391
V W
va_arg 220,339 Warning detection 82
va_end 220,341 WARNINGLEVEL 82
va_list 207 Warnings 201
va_start 220,342 WATCHDOG 150
VARBANKING 81,353 whitespace character, defined 381
Variable-length argument list wild card, defined 381
routines 220 WL 82
Variable-Length Argument List
Routines X
va_arg 220
va_end 220 XBPSTACK 145
va_start 220 XBPSTACKTOP 145
Variable-length argument lists 50 XBYTE 180,211
Variables, notational xdata 88
conventions 5 XDATALEN 144
VB 81,353 XDATASTART 144
vertical bar, use of 5 XOFF 153
vprintf 217,343 XON 153
vsprintf 217,345 XWORD 180,211