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

Necessary to save used registers in assembly ?

I am using assembly language routines
called from C code.
Within the assembly routines, is it necessary to save the registers used?

Ex:
MY_ASM_ROUTINE:
PUSH ACC ; necessary ?
CLR A ; overwrite ACC
POP ACC
RET

main(){
MY_ASM_ROUTINE();
}

Or does the C compiler assume that
registers can be overwritten by
calls to routines?

I couldn't find the answer in the manuals.

Thanks in advance
Jim Burke

Parents
  • Here are a few things to consider:

    1. There is no difference between a C function and an assembly function.

    2. A called assembler function may use all registers A, B, R0-R7, and DPTR without saving and restoring them.

    3. It is ALWAYS the caller's responsibility to reload register contents after a function call.

    4. If an assembler function (called from C) takes arguments and/or returns values, it must use the same conventions as the C compiler. Refer to the manual.

    5. The regfile is used to perform global register optimizations. Basically, a bipmap of the registers used in each function is built up and used by the C compiler to optimize saving and restoring registers.

    Hope this helps.

    Jon

Reply
  • Here are a few things to consider:

    1. There is no difference between a C function and an assembly function.

    2. A called assembler function may use all registers A, B, R0-R7, and DPTR without saving and restoring them.

    3. It is ALWAYS the caller's responsibility to reload register contents after a function call.

    4. If an assembler function (called from C) takes arguments and/or returns values, it must use the same conventions as the C compiler. Refer to the manual.

    5. The regfile is used to perform global register optimizations. Basically, a bipmap of the registers used in each function is built up and used by the C compiler to optimize saving and restoring registers.

    Hope this helps.

    Jon

Children
  • Thanks for the reply Jon.

    I can therefore assume that the compiler
    will restore registers after a call,
    even if it is optimizing performance by
    using registers. I do not need to
    save used registers in an assembly
    program ( an ISR is an exception ) since
    the caller will assume its registers may have been overwritten.

    Thanks again for your reply.
    It eliminated my doubt.

    Jim

  • >1. There is no difference between a C function and an assembly function.

    >5. The regfile is used to perform
    >global register optimizations.
    >Basically, a bipmap of the registers
    >used in each function is built up and
    >used by the C compiler to optimize >saving and restoring registers.

    I think you forget about $REGUSE directive.

    Sentence (1.) is not true.
    Main difference between C and Assembler functions is that C compiler don't know anything about using registers in assembler function.

    So, to force compiler apply 'global optimisation' under assembler functions user MUST explicitly declare used registers with $REGUSE directive.

    For example:
    --- file SWAPBYTE.C ---

    #pragma  SRC(SWAPBYTE.a51)
    
    
    #pragma asm
       $REGUSE _SwapByte(A, R7 )
    #pragma endasm
    
    uchar SwapByte(unsigned char Byte)
    {
      ACC = Byte;
    #pragma asm
      swap a
    #pragma endasm
      return( ACC );
    }
    



    P.S.
    Without $REGUSE compiler generate code for all callers of SwapByte() with reloading registers R0,R1,...,R6,DPTR,B.

    Adding lines:
    #pragma asm
       $REGUSE _SwapByte(A, R7 )
    #pragma endasm
    
    in my current project reduce code size
    from 44639 to 44489 bytes.