Keil Logo

C51: ABSOLUTE REGISTERS AND USING DIRECTIVE

Information in this article applies to:

  • C51 Version 5.50

SYMPTOMS

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?

CAUSE

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.

RESOLUTION

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.

MORE INFORMATION

FORUM THREADS

The following Discussion Forum threads may provide information related to this topic.

Last Reviewed: Tuesday, December 12, 2006


Did this article provide the answer you needed?
 
Yes
No
Not Sure
 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.