
- •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

184 |
Chapter 6. Advanced Programming Techniques |
|
|
Accessing Absolute Memory Locations
The C programming language does not support a method of explicitly specifying the memory location of a static or global variable. There are three ways to reference explicit memory location. You can use the:
Absolute memory access macros
Linker location controls
The _at_ keyword
Each of these three methods is described below.
Absolute Memory Access Macros
First, you may use the absolute memory access macros provided as part of the Cx51 library. Use the following macros to directly access the memory areas of the 8051.
CBYTE |
FCVAR |
CWORD |
DBYTE |
FVAR |
DWORD |
FARRAY |
PBYTE |
PWORD |
FCARRAY |
XBYTE |
XWORD |
Refer to “Absolute Memory Access Macros” on page 212 for definitions of these 6 macros.

Keil Software — Cx51 Compiler User’s Guide |
185 |
|
|
Linker Location Controls
The second method of referencing explicit memory location is to declare the variables in a stand-alone C module, and use the location directives of the BL51 Linker/Locator to specify an absolute memory address.
In the following example, assume that we have a structure called alarm_control that we want to reside at address 2000h in xdata. We start by entering a source file named ALMCTRL.C that contains only the declaration for this structure.
.
.
.
struct alarm_st {
unsigned int alarm_number; unsigned char enable flag; unsigned int time_delay; unsigned char status;
}; |
|
|
xdata struct alarm_st alarm_control; |
|
|
. |
|
|
. |
|
|
. |
|
|
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 Lx51 Linker/Locator allows |
|
|
you to specify the base address of any segment by using the location directives. |
6 |
|
For BL51 you must use the XDATA directive, since the alarm_control |
||
variable was declared to reside in xdata: |
|
|
BL51 ... |
almctrl.obj XDATA(?XD?ALMCTRL(2000h)) … |
|
For LX51 the SEGMENTS directive is used to locate the segment in xdata space:
LX51 ... almctrl.obj SEGMENTS(?XD?ALMCTRL(X:0x2000)) …
This instructs the linker to locate the segment named ?XD?ALMCTRL at address 2000h in the xdata memory area.
In the same way you may also locate segments in the other memory areas like code, xdata, pdata, idata, and data. Refer to the A51 Macro Assembler User’s Guide for more information about the Linker/Locator.

186 |
Chapter 6. Advanced Programming Techniques |
|
|
The _at_ Keyword
The third method of accessing absolute memory locations is to use the _at_ keyword when you declare variables in your C source files. The following example demonstrates how to locate several different variable types using the _at_ keyword.
struct link |
{ |
|
struct link idata *next; |
||
char |
code |
*test; |
}; |
|
|
struct link list idata _at_ 0x40; |
||
char xdata text[256] |
_at_ 0xE000; |
|
int xdata i1 |
|
_at_ 0x8000; |
void main ( void ) { link.next = (void *) 0; i1 = 0x1234; text [0] = 'a';
}
/* list at idata 0x40 */ /* array at xdata 0xE000 */ /* int at xdata 0x8000 */
Refer to “Absolute Variable Location” on page 104 for more information about the _at_ keyword.
NOTE
If you use the _at_ keyword to declare a variable that accesses an XDATA peripheral, you may require the volatile keyword to ensure that the C compiler does not optimize out necessary memory accesses.
6