ARM Technical Support Knowledge Articles


Applies to: C51 C Compiler


Information in this article applies to:


I'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?


The Keil C51 Compiler generates relocateable object files that can interface easily to relocateable assembler programs. The file KeilC51ASMTEMPLATE.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

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



Article last edited on: 2005-07-15 10:22:15

Rate this article

Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential