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

ARM, C and Assembly

Hi,
I want to write some subroutines with µVision3 in assembler and use this in my C-Funktions (Philips LPC2148). For example I have wrote(copied) this one:

//--------------------------------------------
//cpu_asm.asm 
//--------------------------------------------

NO_INT          EQU     0xC0

AREA    OSCPUSRSave, CODE
        PUBLIC  __OSCPUSRSave

__OSCPUSRSave   PROC    CODE32


    MRS     R0,CPSR
    ORR     R1,R0,#NO_INT
    MSR     CPSR_c,R1

    MRS     R1,CPSR
    AND     R1,R1,#NO_INT
    CMP     R1,#NO_INT

    BNE     __OSCPUSRSave
    BX      LR

ENDP

END

//--------------------------------------------


After that i declared in a C-File:

extern void __OSCPUSRSave(void);

Now i get every time the error Message: ***Warning L123: UNRESOLVED EXTERNAL SYMBOLS and ***ERROR L128: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: __OSCPUSave?T ADDRESS: 000003AAH I think the linker have to find the procedur because i wrote: PUBLIC __OSCPUSRSave , but he didn't.
I hope someone can help me, thanks.

Parents Reply Children
  • The first thing to note is that your assembler code is ARM code and that you are using the Keil ARM compiler.

    __OSCPUSRSave   PROC    CODE32
    

    The second thing to note is that the linker is looking for a routine written for THUMB mode as evidenced by the ?T at the end of symbol in the linker error message.

    ***Warning L123: UNRESOLVED EXTERNAL SYMBOLS and ***ERROR L128: REFERENCE MADE TO UNRESOLVED EXTERNAL SYMBOL: __OSCPUSave?T ADDRESS: 000003AAH
    

    You can tell from this that the C file that references the function was compiled for THUMB mode. The ability to call code written in one mode from code written in another mode is called interworking. Veneers can be added to switch modes as needed. This is handled automatically by the compiler\linker for C code when interworking is enabled. You need to mimic the same operation when you write assembler code. Your function prototype was

    extern void __OSCPUSRSave(void);
    

    C code compiled for THUMB will look for a function called __OSCPUSRSave?T when it comes to the link stage. C code compiled for ARM will look for a function called __OSCPUSRSave?A when it comes to the link stage. You need to follow this convention to interface C to assembly. Note that this information is based on observing the code that is generated by the compiler. It's probably in the manual somewhere but I couldn't find it. The following sample code from the manual refers to this convention though.

    EXTERN DATA   (val)
    
    PUBLIC func2?A
    PUBLIC func2?T
    
    AREA ?PR?func2, CODE
    ; veneer code for ARM entry
    func2?A    PROC    CODE32       ; entry point for ARM mode call
               LDR     R12,[R15]    ; load Thumb entry
               BX      R12          ; switch to Thumb mode
               DD      func2?T
               ENDP
    
    ; entry point for Thumb mode call
    func2?T    PROC    CODE16
               PUSH    {LR}         ; save return address to stack
    ;---- Variable 'x1' passed in Register 'R0'
    ;---- Variable 'x2' passed in Register 'R1'
    ;   y = func1 (*x1, x2);
               LDR     R0,[R0,#0x0] ; load content of x1
    ;
    ;---- Variable 'v' passed in Register 'R0'
    ;---- Variable 'p' passed in Register 'R1'
               BL      func1?T      ; function call
    
    ;---- The function value of 'func1' is returned in Register 'R0'
    ;---- temporary Variable 'y' is saved in Register 'R0'
    ;   val += y;
               LDR      R1,=val      ; address of val
               LDR      R2,[R1,#0x0] ; load val
               ADD      R2,R0        ; add y to val
               STR      R2,[R1,#0x0] ; store val
    ;   return (y);
               POP      {R3}
               BX       R3
    
               ENDP
    
               END
    

  • Patrick Noonan you say it like it is. Your example had helped me. Thanks

  • Ok,
    Good one, THanks a lot,
    Bless you,