The C51 manual states, "The using attribute may not be used in functions that return a value in registers" and goes on to state, "Even when you use the same register bank, functions declared with the using attribute cannot return a bit value." It's clear that a bit value set in the carry flag isn't passed back to the calling function. It's not clear why a function "using" a register bank can't call another function "using" the same register bank: The same bank select bits are being pushed, loaded, and popped. Am I missing something, or is this an OK thing to do?
If the manual says "don't do it" - then just don't do it!
If you want to know the inner workings, then look at the generated assembler...
I am looking at the assembler output. That's why I stated the question the way I did. I don't understand why the manual states "don't do it" when the assy code appears to indicate it should work fine: A function "using" a register bank first pushes the PSW containing the caller's register bank bits, then loads the PSW with the same register bank bits, place the function result in the expected absolute-addressed registers, then pops the PSW which returns the same bank bit settings to the caller, which pulls the result from the same registers. Ergo, the result appears to be returned just fine.
In this particular case, the calling function is an interrupt handler. If the called function isn't declared using the same register bank, things obviously get bolluxed up. The called function will (probably) use bank zero, fouling up whatever was happening when the interrupt occurred. The called function could pass the result in memory rather than returning it in registers, incurring extra store and load operations. The interrupt trap could push all registers on the way in and pop them back on the way out. All this is not necessary if my analysis of the assy code is correct.
My current project is the first in which I've used the 8051 architecture and I was hoping to hear from someone with more experience using the parts.
My experience of using C51 is that it has some very clever optimisations.
So, although it may look fine in your "test case", there may well be other situations that rely upon you taking their word on this.
If you really want the internal details, I guess you'll have to contact Keil support direct...
... had an intended feature. This feature was found to have a problem with one particular case. Since fixing this problem would require changing the whole project (the basic architecture made it impossible to fix) it was decided to remove the feature. Some code that supported the feature was not removed. the documentation was changed so this feature was not mentioned.
This seems very similar
Erik
You may be interested in this post
http://www.keil.com/forum/docs/thread13641.asp
--Cpt. Vince Foster 2nd Cannon Place Fort Marcy Park, VA
Vince:
Thx. for the reference. I think the point you made to "ensure that both code sections are identical" is the key to this issue. I certainly can't see anything that could cause a problem when doing so.
And the only thing worse than macros is \t characters in source code... ;-)
The using attribute may not be used in functions that return a value in registers
This warning appears on the manual page: http://www.keil.com/support/man/docs/c51/c51_le_regbankspec.htm
The reason for this warning should be clear...
So, as you can see, the reason for this warning has to do with the register bank getting restored to that of the caller.
The remainder of the warning states that: "You must exercise extreme care to ensure that register bank switches are performed only in carefully controlled areas. Failure to do so may yield incorrect function results."
So, as long as you do that (and make sure you are in the same register bank) you should be OK.
The final sentence of the warning, "Even when you use the same register bank, functions declared with the using attribute cannot return a bit value." should also be clear.
Saving and restoring the register banks involves pushing and popping the PSW which contains the carry flag (which contains the bit return value). Restoring the register banks also restores the carry flag. Therefore, you lose the intended return bit value.
You may want to take a look at the Registerbank directive (http://www.keil.com/support/man/docs/c51/c51_registerbank.htm).
My personal advice is to make sure this is what you REALLY want to do. It's not difficult to make things work but this was usually a sign to me when I was at Keil that there was a potential design problem.
Jon