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
I'm a new user of Keil products, and i've the same problem. But at page 135 of 'C51 Compiler User's Guide (01.97)' you can read: "Assembler functions can change all register contents in the current selected register bank as well as the content of th register ACC, B, DPTR, PSW. [..]". IMHO this behaviour seems to be not optimized. The best solution seems to be REGFILE directives of C51 and BL51. But I don't know how they work. I will investigate. Marcello
Hi Marcello, I agree, REGFILE seems worth investigating. I'm using v.4.10 of the compiler. It mentions REGFILE, and the .reg files, but I can not find more information on their contents or an example of a .reg file. I've been using the compiler on one project for 4 years, as part of a team of a half-dozen programmers. I reviewed all the assembly routines and found that most did save their used registers. A new project I'm looking at does not save it's used registers, with the exception of the ISR's. The code has been working for 10 years however. I'm just wondering if it is by luck, or if possibly a small change might then lead to registers in the C rotines to be overwritten when they call assembly routines. In the back of the manual rev 07.94, in the appendix H: 'Writing Optimized Code', under the heading 'Local Variables', it states: "As part of the optimization process, the compiler attempts to maintain local variables in registers." Thus, a routine that used optimization and called assembly routines that did not save their used registers, would have the potential to corrupt the callers registers. The compliler also defaults to the highest level of optimization, level 6. This includes level 4 and Register Variable optimization. I'll either set the optimization level below 4, or add assembly code to save used registers. Jim
Hi Jim, I found these documents http://www.keil.com/support/docs/939.htm http://www.keil.com/support/docs/904.htm They tell about REGFILE directives, but both apply to C51 v5.5 and I don't know if they can hel you. I understand that REGFILE directives are to be used in: 1. Assembly code (to specify which register are used in each function) 2. In C compiling parameters (to tell the compiler to optimize register usage following information retrieved in 1.) 3. In BL51 compiling parameters (why ??) I think that if you don't use REGFILE directives C51 compiler assumes that *all* register are corrupted in the Assembly routine, so it "disables" the 'Register variables optimization'. Try to analyze the Assembly file created by C51, so you can understand how it uses register to store variables first and after Assembly-routine callings. (If C51 v4.10 doesn't allow to create SRC file from C modules use a debugger or a disassembler) Tomorrow (in Italy is already 8:00 PM), I hope to make some test. Marcello
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