This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

register variable is clobbered by passing parameter to a function


target-mcu: AVR
gcc-version: 3.3.1  (latest WINAVR-distribution)

When I declare an often used variable as register, the variable is modified
after calling a function.
Example-code:

register  char often_used_variable asm ("r16");
char foo;
void function1 (char p1, char p2, char p3, char p4, char p5) {   };

int main (void)
{
often_used_variable = 5;
function1 (6,7,8,9,10);
foo = often_used_variable;
}

is compiled to (opt. level=s):

int main (void)
{
.
.
often_used_variable = 5;
ldi r16, 0x05 ; 5       <-- 
function1 (6,7,8,9,10);
ldi r16, 0x0A ; 10   <--- here it happens
ldi r18, 0x09 ; 9
ldi r20, 0x08 ; 8
ldi r22, 0x07 ; 7
ldi r24, 0x06 ; 6
rcall .-24 ; 0x4a

foo = often_used_variable;
sts 0x0060, r16

} // main
.
and foo is now 10 instead of 5.

but without any warning.
If I use the register r18, I get a compiler-warning: call clobbered register
... (and the code is inoperative too).
I could not found anything about this behaviour in the gcc-online-docs.
It only happens with parameters passed to a function, that the register
variable is wasted.
If I use r14 and I have 6 parameters, the result is the same! (r14 is
wasted).
In a bigger application I use an often used variable in such a matter. It
saves a lot of space and runtime. And it works. But once a day it wouldn't
work and I debugged. It was when I added a function with some more
parameters. I know, that the register-keyword is not obligatory for the
compiler, but then he shall give me at least a warning.
Now I am not shure, how safe is my code, are there more side effects?

if I make in my example-code the variable local, the same happens.

K&R says, the compiler can ignore the keyword. But in this case he doesn't
ignores it, he uses the register but then he uses it for himself (for the
parameter passing).
If it is a local var, too.

When I debugged my application, I noticed, that in case of register decl.,
the compiler doesn't use the r16, in case of standard decl. he used the r16.
So I think, it is a bug, that only in the parameter passing he "forgot" to
use another register for passing.

Bug or feature?
Each comment is welcome.

Best regards
Wolfgang


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]