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

is unsigned char EXTERN-able? Linking problem...

Hi,

I have a program that calls Assembly from C. The odd behaviour is that one assembly function links fine, while the other gives me UNRESOLVED EXTERNAL SYMBOL and REFERENCE TO UNRESOLVED EXTERNAL (L1 and L2) warnings from the linker. both routines follow the exact same template, with the exception that the one that gives me the warnings passes paramaters. I would assume unsigned char is a valid type to pass to assembly via an extern declaration?!? Code fragments are below:

The C source calling the assembly routines:

#define MPU_READ_ADDR	0
...
void coInitReg();        // C protos
void xint_handler (void);

// these are assembly
extern void c_init(void);
extern unsigned char mpu_read(unsigned char);
...
void coInitReg()
{
    cinit();    // call assembly -> OK
    ...
}

void xint_handler(void)
{
    unsigned char address = MPU_READ_ADDR;
    ...
    mpu_data = mpu_read(address); // call assembly -> L1/L2 WARNING!
    ...
}

this is a fragment of the assembly:
PUBLIC c_init
PUBLIC mpu_read

...
; this one seems OK
UTILS	SEGMENT CODE
	RSEG UTILS
c_init:	mov R0,#13
        ...
        ret

; this one give me the L1 & L2 warnings!
MPU_RD	SEGMENT CODE
	RSEG MPU_RD

mpu_read:
	MOV A,R7	; put passed parameter from R7 in A
        JNZ rddata	; jump
        ...
        MOV R7,P2        ; into R7 for ret, as the compiler asks for
        ret
        ...

Any clues what the differences are that would create the linker warnings?

thanks

Jeff

  • I think it'd help if you showed the full text of those linker messages...

    Have you read the section "Interfacing 'C' and Assembler" in the C51 Manual?

    C51 uses different prefixes on the generated names depending on things like return value & number of parameters. I forget the precise details, but it's all there in the Manual!

  • Fixed. The error in my logic was the assumption that the compiler would insert the underscore at code generation time and resolve the reference, which was how I interpreted the text below.

    From the C51 manual:
    Functions that pass
    parameters in registers are flagged by the Cx51 compiler with an underscore
    character ('_') prefixed to the function name at code generation time

    MANUALLY adding an underscore to the function in the assembly file fixed it.

    Note that I make it a point to throughly read the manuals and search archives before posting anything here.

    thanks,

    Jeff

  • "The error in my logic was the assumption that the compiler would insert the underscore at code generation time and resolve the reference"

    Yes, the Compiler does that - but you wrote the code in Assembler.

    The Assembler has no idea that you intend the function to be called by C51 (or PL/M or anything else) - so if you want it to be C51-compatible (or whatever), it is entirely up to you to make it so!