This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

C mixed with assembler

I want to use C mixed with assembler.
I wrote the following experimental program:
void main(void){
char i,a[20];
for(i=0;i<20;i++)a[i]=i;
#pragma ASM
MOV A,#29H
MOV R2,A
..etc..
#pragma ENDASM
}

When building this program together with Startup.a51, the following linker warning appears
WARNING L1: UNRESOLVED EXTERNAL SYMBOL
SYMBOL: ?C_START
MODULE: .\Startup.obj (?C_STARTUP)
WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
SYMBOL: ?C_START
MODULE: .\Startup.obj (?C_STARTUP)
ADDRESS: 2029H

After adding some other statements the program became this:

#include <stdio.h>
#include "setUpSerPort.h"

void main(void){
char i,a[20];
for(i=0;i<20;i++)a[i]=i;
setUpSerialPort();
printf("program running");
#pragma ASM
MOV A,#29H
MOV R2,A
..etc..
#pragma ENDASM
}

file setUpSerialPort.h contains
#ifndef setUpSerPort_h
#define setUpSerPort_h

void setUpSerialPort();

#endif

file setUpSerialPort. c contains
void setUpSerialPort(void){
#ifndef MONITOR51
SCON = 0x50;
TMOD = 0x20;
TH1 = 221;
TR1 = 1;
TI = 1;
#endif
}

When building this project thelinker warnings have gone! But why??


With regards.

  • When you compile a C file, the C compiler includes external references to the startup code. This way, you don't have to manually include the startup code if you have a simple C program like:

    void main (void)
    {
    while (1);
    }
    

    When you create a program that consists of a singel C module that you compile with #pragma src, the output is a .SRC file that must be assembled by the A51 assembler. In this case, the external references for the startup code are not generated automatically (by the assembler, that is) so you must generate them manually.

    The easiest way to do this is to specify the C library on the linker command line. Refer to the linker manual to determine which library you need.

    Another way around this problem is to add another C file (that you compile with the C compiler) to your project. The startup reference will be generated (by the compiler) and stuffed in the resulting .OBJ file.

    The following knowledgebase article may shed a little more light on this issue.

    http://www.keil.com/support/docs/1646.htm

    Jon

  • To make your first example work, some C code needs to be compiled into an object module. This allows the compiler to 'tell' the linker to use the C enviroment. (Using the ASM directive prevented any C object module from being created.) Compling any C code would have fixed things, say "setUpSerialPort.c" or even an empty.c file.