|
|||||||||||
|
Technical Support Support Resources
Product Information |
C51: ADDING C FUNCTIONS TO EXISTING ASSEMBLER CODEInformation in this article applies to:
QUESTIONI'm using the Keil C51 Tools and have successfully written 8051 programs only in assembly language. Now I need add C code to my assembly program. I want to keep as much as possible of my existing assembly code. Are there some guidelines on how to mix assembly and C code using the Keil C51 compiler? How can I access memory locations from my C programs that I have reserved in assembly code? ANSWERThe Keil C51 Compiler generates relocateable object files that can interface easily to relocateable assembler programs. The file Keil\C51\ASM\TEMPLATE.A51 shows you how to structure relocateable assembly modules. This file defines several variables, for example:
PUBLIC data_variable
PUBLIC xdata_array
data_seg_name SEGMENT DATA ; segment for DATA RAM.
RSEG data_seg_name ; switch to this data segment
data_variable: DS 1 ; reserve 1 Bytes for data_variable
xdata_seg_name SEGMENT XDATA ; segment for XDATA RAM
RSEG xdata_seg_name ; switch to this xdata segment
xdata_array: DS 500 ; reserve 500 Bytes for xdata_array
You access these variables in your C code with:
extern unsigned char data_variable;
extern unsigned xdata xdata_array[500];
void test (void) {
xdata_array[data_variable] = 1; // write 1 to memory addressed by @xdata_array+data_variable;
}
To reduce data RAM requirements of your application, the BL51/Lx51 Linker/Locater performs call tree analysis of the complete application program. Therefore, the linker needs to be able to distinguish between constants and program code and it must also be able to determine the local data segments for your program code. For this reason you should change the segment naming conventions of your assembler program to the segment names used by the C51 Compiler. Detailed information can be found in Application Note 149: Data Overlaying and Code Banking with A51 Assembler Modules. For each interrupt function written in assembly, you must create a separate segment for the interrupt vector using CSEG AT.
CSEG AT 03H ; EXT0 interrupt vector
SETB mybit ; interrupt function code
RETI
CSEG AT 0BH ; Timer 0 interrupt vector
LJMP timer0isr
?BI?timer0?isr_module SEGMENT BIT OVERLAYABLE ; bit segment
RSEG ?BI?timer0?isr_module
isrbit: DBIT 1
?PR?timer0?isr_module SEGMENT CODE ; program code
RSEG ?PR?timer0?isr_module
timer0isr: ; put your program code here
SETB isrbit ; interrupt function code
RETI
MORE INFORMATION
SEE ALSOFORUM THREADSThe following Discussion Forum threads may provide information related to this topic. Last Reviewed: Friday, July 15, 2005 | ||||||||||
|
|||||||||||
Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.