- •Chapter 1. Introduction
- •Support for all 8051 Variants
- •Books About the C Language
- •Chapter 2. Compiling with the Cx51 Compiler
- •Environment Variables
- •Running Cx51 from the Command Prompt
- •ERRORLEVEL
- •Cx51 Output Files
- •Control Directives
- •Directive Categories
- •Reference
- •Chapter 3. Language Extensions
- •Keywords
- •Memory Areas
- •Program Memory
- •Internal Data Memory
- •External Data Memory
- •Far Memory
- •Special Function Register Memory
- •Memory Models
- •Small Model
- •Compact Model
- •Large Model
- •Memory Types
- •Explicitly Declared Memory Types
- •Implicit Memory Types
- •Data Types
- •Bit Types
- •Special Function Registers
- •sbit
- •Absolute Variable Location
- •Pointers
- •Generic Pointers
- •Pointer Conversions
- •Abstract Pointers
- •Function Declarations
- •Function Parameters and the Stack
- •Passing Parameters in Registers
- •Function Return Values
- •Specifying the Memory Model for a Function
- •Specifying the Register Bank for a Function
- •Register Bank Access
- •Interrupt Functions
- •Reentrant Functions
- •Chapter 4. Preprocessor
- •Directives
- •Stringize Operator
- •Predefined Macro Constants
- •Chapter 5. 8051 Derivatives
- •Analog Devices MicroConverter B2 Series
- •Atmel 89x8252 and Variants
- •Dallas 80C320, 420, 520, and 530
- •Arithmetic Accelerator
- •Data Pointers
- •Library Routines
- •Philips 8xC750, 8xC751, and 8xC752
- •Philips 80C51MX Architecture
- •Philips and Atmel WM Dual DPTR
- •Customization Files
- •STARTUP.A51
- •INIT.A51
- •XBANKING.A51
- •Basic I/O Functions
- •Memory Allocation Functions
- •Optimizer
- •General Optimizations
- •Options for Code Generation
- •Segment Naming Conventions
- •Data Objects
- •Program Objects
- •Interfacing C Programs to Assembler
- •Function Parameters
- •Parameter Passing in Registers
- •Parameter Passing in Fixed Memory Locations
- •Function Return Values
- •Using the SRC Directive
- •Register Usage
- •Overlaying Segments
- •Example Routines
- •Small Model Example
- •Compact Model Example
- •Large Model Example
- •Data Storage Formats
- •Bit Variables
- •Signed and Unsigned Long Integers
- •Generic and Far Pointers
- •Floating-point Numbers
- •Accessing Absolute Memory Locations
- •Absolute Memory Access Macros
- •Linker Location Controls
- •The _at_ Keyword
- •Debugging
- •Chapter 7. Error Messages
- •Fatal Errors
- •Actions
- •Errors
- •Syntax and Semantic Errors
- •Warnings
- •Chapter 8. Library Reference
- •Intrinsic Routines
- •Library Files
- •Standard Types
- •va_list
- •Absolute Memory Access Macros
- •CBYTE
- •CWORD
- •DBYTE
- •DWORD
- •FARRAY, FCARRAY
- •FVAR, FCVAR,
- •PBYTE
- •PWORD
- •XBYTE
- •XWORD
- •Routines by Category
- •Buffer Manipulation
- •Character Conversion and Classification
- •Data Conversion
- •Math Routines
- •Memory Allocation Routines
- •Stream Input and Output Routines
- •String Manipulation Routines
- •Miscellaneous Routines
- •Include Files
- •8051 Special Function Register Include Files
- •ABSACC.H
- •ASSERT.H
- •CTYPE.H
- •INTRINS.H
- •MATH.H
- •SETJMP.H
- •STDARG.H
- •STDDEF.H
- •STDIO.H
- •STDLIB.H
- •STRING.H
- •Reference
- •Compiler-related Differences
- •Library-related Differences
- •Appendix B. Version Differences
- •Version 6.0 Differences
- •Version 5 Differences
- •Version 4 Differences
- •Version 3.4 Differences
- •Version 3.2 Differences
- •Version 3.0 Differences
- •Version 2 Differences
- •Appendix C. Writing Optimum Code
- •Memory Model
- •Variable Location
- •Variable Size
- •Unsigned Types
- •Local Variables
- •Other Sources
- •Appendix D. Compiler Limits
- •Appendix E. Byte Ordering
- •Recursive Code Reference Error
- •Problems Using the printf Routines
- •Uncalled Functions
- •Using Monitor-51
- •Trouble with the bdata Memory Type
- •Function Pointers
- •Glossary
- •Index
118 |
Chapter 3. Language Extensions |
|
|
Function Declarations
The Cx51 compiler provides a number of extensions for standard C function declarations. These extensions allow you to:
|
Specify a function as an interrupt procedure |
||
|
Choose the register bank used |
|
|
|
Select the memory model |
|
|
|
Specify reentrancy |
|
|
|
Specify alien (PL/M-51) functions |
|
|
3 |
|
||
You may include these extensions or attributes (many of which may be |
|||
|
combined) in the function declaration. Use the following standard format for |
||
|
|||
|
your Cx51 function declarations. |
|
|
|
return_type funcname ( args ) |
{small | compact | large} |
|
|
|
|
reentrant interrupt n using n |
|
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.
Keil Software — Cx51 Compiler User’s Guide |
119 |
|
|
Function Parameters and the Stack
The stack pointer on the classic 8051 accesses internal data memory only. The Cx51 compiler locates the stack area immediately following all variables in the internal data memory. The stack pointer accesses internal memory indirectly and can use all of the internal data memory up to the 0xFF limit.
The total stack space of the classic 8051 is limited: only 256 bytes maximum. Rather than consume stack space with function parameters or arguments, The Cx51 compiler 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 parameters, as needed, from these fixed memory 3 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
The Cx51 compiler uses extended stack areas that are available in some enhanced 8051 variants. In this way the stack space can be increased to several KiloBytes.
By default, the Cx51 compiler passes up to three function arguments in registers. This enhances speed performance. For more information, refer to “Passing Parameters in Registers” on page 120.
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.
120 |
Chapter 3. Language Extensions |
|
|
Passing Parameters in Registers
The Cx51 compiler allows up to three function arguments to be passed in CPU registers. This mechanism significantly improves system performance as arguments do not have to be written to and read from memory. Argument or parameter passing can be controlled by the REGPARMS and NOREGPARMS control directives defined in the previous chapter.
The following table details the registers used for different argument positions and data types.
3 |
|
Argument Number |
char, 1-byte ptr |
int, 2-byte ptr |
long, float |
generic ptr |
|
|
1 |
R7 |
R6 & R7 |
R4—R7 |
R1—R3 |
|
|
|
2 |
R5 |
R4 & R5 |
R4—R7 |
R1—R3 |
|
|
|
|
3 |
R3 |
R2 & R3 |
|
R1—R3 |
|
|
|
|
If no registers are available for argument passing, fixed memory locations are used for function parameters.
Function Return Values
CPU registers are always used for function return values. The following table lists the return types and the registers used for each.
Return Type |
Register |
Description |
bit |
Carry Flag |
|
char, unsigned char, |
R7 |
|
1-byte ptr |
|
|
int, unsigned int, |
R6 & R7 |
MSB in R6, LSB in R7 |
2-byte ptr |
|
|
long, unsigned long |
R4-R7 |
MSB in R4, LSB in R7 |
float |
R4-R7 |
32-Bit IEEE format |
generic ptr |
R1-R3 |
Memory type in R3, MSB R2, LSB R1 |
NOTE
If the first parameter of a function is a bit type, then other parameters are not passed in registers. This is because parameters that are 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.
Keil Software — Cx51 Compiler User’s Guide |
121 |
|
|
Specifying the Memory Model for a Function
A function’s arguments and local variables are stored in the default memory space specified by the memory model. Refer to “Memory Models” on page 94 for more information.
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 */ |
extern int calc (char i, int b) large reentrant;
extern int func (int i, float f) large; 3 extern void *tcp (char xdata *xp, int ndx) small;
int mtest (int i, int y) /* Small model */
{
return (i * y + y * i + func(-1, 4.75));
}
int large_func (int i, int k) large /* Large model */
{
return (mtest (i, k) + 2);
}
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. Occasionally, the small model cannot satisfy the requirements of a very large program and other memory models must be used. For this situation, you may declare that a function use 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 to use. Stack access in the SMALL model is more efficient than in the LARGE model.