|ARM Technical Support Knowledge Articles|
Applies to: C51 C Compiler
Information in this article applies to:
I have a question regarding the A51 AR0-AR7 registers and the USING directive. To simplify the discussion I will consider only AR0 (the extension to AR1-AR7 being obvious).
I had thought that the only effect of the USING directive was to cause every instance of AR0 in the assembly instructions that follow to be replaced with 0x0 if "USING 0", 0x8 if "USING 1", 0x10 if "USING 2", and 0x18 if "USING 3". If there is no USING directive prior to the instance of AR0 in the file, then AR0 is 0x0 (the default is "USING 0").
I have reviewed an ISR that I have written and am now convinced that my understanding of AR0-AR7 is incorrect. At the beginning of the assembly code, AR0-AR7 are saved on the stack. At the end, AR0-AR7 are restored from the stack. Since there is no USING directive, AR0 is RAM address 0. That is, the ISR saves and restores registers from Register Bank 0. Later, the ISR uses some of the registers R0-R7 as targets.
Let's suppose that before the interrupt, the active bank was Bank 2. Since the ISR does nothing to change the active register bank, it has corrupted the Bank 2 register values by writing R1, R2, R3 and R7, and the save/restore of Bank 0 was a waste of time.
What's wrong with my analysis of this code example?
Your analysis is correct. That is the reason for the USING directive. The compiler uses an implicit USING 0 so that it can optimize the use of normal and absolute registers. This causes problems when you have a function in one register bank call a function written for a different register bank.
To resolve the problem, you may specify a USING directive for the interrupt routine. Or, you may create a function or ISR that is register bank independent using the NOAREGS directive.
To create functions (or interrupts) that are register bank independent, use the NOAREGS directive. This directive tells the compiler NOT to use absolute register accesses (with 0x00, 0x08, 0x10, or 0x18 for R0 in register bank 0, 1, 2, and 3).
The NOAREGS directive makse your program size grow a little, but the functions may be called from any register bank.
Note that your application may include some functions compiled with NOAREGS and some compiled with AREGS.
Article last edited on: 2006-12-12 05:21:58
Did you find this article helpful? Yes No
How can we improve this article?