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

Output ASM Code in COD differs from LST

I have a problem like this. I have mixed ASM and C source code. After compiling when I look LST file where is a code made by CA it looks like bellow. And it is good for me. Function is called by direct BL.

  263:         mem_cpy(SubExt, ptrByte, bLength);
 00000120  1C28      MOV         R0,R5 ; bLength
 00000122  0602      LSL         R2,R0,#0x18 ; bLength
 00000124  0E12      LSR         R2,R2,#0x18
 00000126  A800      ADD         R0,R13,#0x0
 00000128  1C21      MOV         R1,R4 ; ptrByte
 0000012A  F7FF      BL          mem_cpy?T  ; T=0x0001  (1)
 0000012C  FF69      BL          mem_cpy?T  ; T=0x0001  (2)
But for some reason in linker this code is converted to some Indirect Call etc stuff. And it is not good at all for my purpposes. Function is called by LDR R3 .. BX R3.
  263:         mem_cpy(SubExt, ptrByte, bLength);
 000001C4  1C28      MOV         R0,R5 ; bLength
 000001C6  0602      LSL         R2,R0,#0x18 ; bLength
 000001C8  0E12      LSR         R2,R2,#0x18
 000001CA  A800      ADD         R0,R13,#0x0
 000001CC  1C21      MOV         R1,R4 ; ptrByte
 000001CE  4B44      LDR         R3,[R15,#272] ; PoolRef @0x2E0 ; mem_cpy?T
 000001D0  F000      BL          L_53  ; T=0x01D6  (1)
 000001D2  F801      BL          L_53  ; T=0x01D6  (2)
 000001D4  E000      B           L_54  ; T=0x000001D8
 000001D6          L_53:
 000001D6  4718      BX          R3
 000001D8          L_54:
My memcpy function is not standard and it is made with ASM code.. and it is defined as PUBLIC mem_cpy?T. But same thing happens with every function call :( I'm testing Keil CA and LA 2.42 at the moment. ASM Code looks good in LST file but final COD and HEX files had this wrong looking call procedure.. So I don't like this at all.. Is there a way to avoid this kind of conversion in linker ? Or maybe some ASM/C coding "trick" for this ?

  • I don't know about the ARM tools, but with C51 this would be due to the Linker optimisations.
    That's why the linker produces a separate COD file - because it will be different from the compiler/assembler-generated code in the LST files!


    Does your linker do post-compile optimisation?
    Can you turn it off?

  • Thanx about answer :)


    I'm using Keil ARM tools (CARM,AARM,LARM) 2.42 and uVision 3. I have tried all optimization levels and other options what uVision can offer but without any change. I have also checked CARM,AARM,LARM online manuals.


    When I call standard memcmp functions from string.h or other functions in C sources everything is ok after linking.. But if I try call any of my function in ASM sources from C it will be converted to this "Indirect Call" look. I have also tried several different function prototyping for ASM functions like:

    //#define EXTERN          extern
    //#define EXTERN          const
    //#define EXTERN
    //#define ADDRESS(addr)   __thumb __at addr;
    //#define ADDRESS(addr)   __thumb;
    //#define ADDRESS(addr)   ;
    EXTERN void *mem_cpy(void *Dest, const void *Source, unsigned int length)       ADDRESS(ROM_MEM_CPY)
    
    For C51 linker there seems to be an NOINDIRECT option what will avoid this i think but not for Keil ARM linker :|
    So I'm still looking some solution/trick to access my ASM functions and vars without this "Indirect" and "PoolRef" stuff..

  • It looks like your mem_cpy() function is located at an address out of the 4M (thumb) or 32M (arm) branch range. In this case, the linker automatically creates an address veneer. This is required to 'enlarge' the branch-range to the full address range, so the code is correct and absolutely required here. The compiler does not necessarily see this condition, therefore the code listing must be considered as preliminary. The linker finalizes the code and also gives a .cod listing which reflects the final generated code.

    Peter