3.10 Functions using private register banks(mcs51/ds390)
Keywords: sdccman

#
3.10 Functions using private register banks(mcs51/ds390)

Some architectures have support for quickly changing register sets. SDCC supports this feature with the __using attribute (which tells the compiler to use a register bank other than the default bank zero). It should only be applied to interrupt functions (see footnote below). This will in most circumstances make the generated ISR code more efficient since it will not have to save registers on the stack.

The __using attribute will have no effect on the generated code for a non-interrupt function (but may occasionally be useful anyway3.4).
(pending: Note, nowadays the __using attribute has an effect on the generated code for a non-interrupt function.)

An interrupt function using a non-zero bank will assume that it can trash that register bank, and will not save it. Since high-priority interrupts can interrupt low-priority ones on the 8051 and friends, this means that if a high-priority ISR using a particular bank occurs while processing a low-priority ISR using the same bank, terrible and bad things can happen. To prevent this, no single register bank should be used by both a high priority and a low priority ISR. This is probably most easily done by having all high priority ISRs use one bank and all low priority ISRs use another. If you have an ISR which can change priority at runtime, you're on your own: I suggest using the default bank zero and taking the small performance hit.

It is most efficient if your ISR calls no other functions. If your ISR must call other functions, it is most efficient if those functions use the same bank as the ISR (see note 1 below); the next best is if the called functions use bank zero. It is very inefficient to call a function using a different, non-zero bank from an ISR.