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
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
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 ); }
#pragma asm $REGUSE _SwapByte(A, R7 ) #pragma endasm