We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Using C51 (v6.xx/7.xx) with user defined bank switching (mode 4), which registers must be preserved on the call and return?
R1-R7 must be preserved on the call & return, since these pass parameters & return values.
The carry flag must be preserved on return, since it may return a bit value.
Examining Keil code & examples, it seems that it's ok to trash ACC and DPTR.
What about R0, B and other flags?
I couldn't find anything explicit in the documentation, so have currently taken a conservative position with my (rather complicated) bank switching routine.
Thanks for pointing me in the right direction. It is documented in later versions of L51_BANK.A51 -
; ?B_BANKn is a routine which saves the entry of the ?B_SWITCHn function * ; for the current active bank on the STACK and switches to the * ; bank 'n'. Then it jumps to the address specified by the DPTR * ; register. It is allowed to modify the following registers in * ; the ?B_BANKn routine: A, B, R0, DPTR, PSW * ; * ; ?B_SWITCHn is a function which selects the bank 'n'. This function is * ; used at the end of a user function to return to the calling * ; code bank. Only the following registers may be altered in the * ; ?B_SWITCHn function: R0, DPTR *
Looking through the source, if VAR_BANKING is not used, it's not necessary to preserve A, B or R0 in the ?B_SWITCHn (return) code either. This makes sense, because it's ok to use these registers in the ?B_BANKn (entry) code and C51 never returns values in these registers. The only other thing that may have required register preservation is global register colouring, but this would have required that registers retain their entry values. Keil must disable, or limit global register optimisation for interbank calls.
VAR_BANKING does use A, B and R0, to pass and return values.
Keil must disable, or limit global register optimisation for interbank calls.
A good point. One less charitable option is that it doesn't work in this case... That occurs to me simply because a while back we had some weird problems that we traced down to the global register optimization. Our solution was to disable it. However, maybe our bank switch stubs are trashing something they're not supposed to. Time to review that code.