[Tinyos-help] AVR GCC compiler problems

Janos Sallai sallai at isis.vanderbilt.edu
Fri Feb 29 21:39:19 PST 2008

Function arguments, from left to right, are passed in registers r25 to r8. All arguments take up even number of registers, so if you have a 8-bit argument, then the upper register of the register pair is not used. Stack is only used if the arguments can't be fit into the available registers, or for variable-lenght argument lists.
In this specific case, channel is allocated in r24, id in r23:r22:r21:r20 and mask in r19:r18:r17:r16. As you can see, r24 and r23:r22:r21:r20 are properly set for the second call, but r19:r18:r17:r16 are not. For some reason, avr-gcc assumes that r19:r18:r17:r16 are not changed by the function that is called.
Can you check where in the called function r19:r18:r17:r16 are changed?


From: tinyos-help-bounces at millennium.berkeley.edu on behalf of José Moyano
Sent: Fri 2/29/2008 3:00 PM
To: tinyos-help at millennium.berkeley.edu
Subject: Rv: [Tinyos-help] AVR GCC compiler problems

Below this words, there is the last mail that I sent to tinyos-help. Check the last two "push" at address 00000A4A and 00000A4B. The pushed registers, shouldn't be R18 and R19 instead of R28 and R29? I'm using AT90CAN128, and TinyOS 1.1

----- Mensaje reenviado ----
De: José Moyano <josehmoyano at yahoo.com.ar>
Para: tinyos-help at Millennium.Berkeley.EDU
Enviado: jueves 28 de febrero de 2008, 15:35:43
Asunto: Re: [Tinyos-help] AVR GCC compiler problems

Thanks you all for your help. I check the "app.c", and is ok. Later, I load "main.ihex" with AVR Studio, copy it to notepad, and find the problematic routine code.

+00000A3C:   924F        PUSH    R4               Push register on stack [CPSCAN]
+00000A3D:   925F        PUSH    R5               Push register on stack
+00000A3E:   926F        PUSH    R6               Push register on stack
+00000A3F:   927F        PUSH    R7               Push register on stack
+00000A40:   928F        PUSH    R8               Push register on stack
+00000A41:   929F        PUSH    R9               Push register on stack
+00000A42:   92AF        PUSH    R10              Push register on stack
+00000A43:   92BF        PUSH    R11              Push register on stack
+00000A44:   92CF        PUSH    R12              Push register on stack
+00000A45:   92DF        PUSH    R13              Push register on stack
+00000A46:   92EF        PUSH    R14              Push register on stack
+00000A47:   92FF        PUSH    R15              Push register on stack
+00000A48:   930F        PUSH    R16              Push register on stack
+00000A49:   931F        PUSH    R17              Push register on stack
+00000A4A:   93CF        PUSH    R28              Push register on stack
+00000A4B:   93DF        PUSH    R29              Push register on stack
The parameters are saved here for the first call.
+00000A4C:   2E58        MOV     R5,R24           Copy register
+00000A4D:   014A        MOVW    R8,R20           Copy register pair
+00000A4E:   015B        MOVW    R10,R22          Copy register pair
+00000A4F:   0168        MOVW    R12,R16          Copy register pair
+00000A50:   0179        MOVW    R14,R18          Copy register pair
if (call CANReceive.setReceive[channel](id, mask)) {
+00000A51:   940E0B1A    CALL    0x00000B1A       Call subroutine <<<<<<<<<<< The first call
+00000A53:   2388        TST     R24              Test for Zero or Minus
+00000A54:   F409        BRNE    PC+0x02          Branch if not equal
+00000A55:   C0B0        RJMP    PC+0x00B1        Relative jump
+00000A56:   0000        NOP                      No operation
+00000A57:   0000        NOP                      No operation
+00000A58:   0000        NOP                      No operation
+00000A59:   0000        NOP                      No operation
+00000A5A:   0000        NOP                      No operation
+00000A5B:   0000        NOP                      No operation
+00000A5C:   0000        NOP                      No operation
+00000A5D:   0000        NOP                      No operation
+00000A5E:   0000        NOP                      No operation
+00000A5F:   0000        NOP                      No operation
+00000A60:   0000        NOP                      No operation
+00000A61:   0000        NOP                      No operation
+00000A62:   E087        LDI     R24,0x07         Load immediate
+00000A63:   2E48        MOV     R4,R24           Copy register
+00000A64:   0C45        ADD     R4,R5            Add without carry
The parameters are restored here, for the second call
+00000A65:   01B5        MOVW    R22,R10          Copy register pair
+00000A66:   01A4        MOVW    R20,R8           Copy register pair
+00000A67:   2D84        MOV     R24,R4           Copy register
call CANReceive.setReceive[channel + 7](id, mask);
+00000A68:   940E0B1A    CALL    0x00000B1A       Call subroutine <<<<<<<<<<< The second call

As you can see, in the second call, r20, r22 and r24 are reloaded, but r18 and r16 are not. So one of my 32-bit parameters isn't reloaded. In the called routine, r18 and r19 are used, but not saved in stack, so r18 and r19 change their value. I don't know if this is an error, is it? Can I avoid this behavior somehow?

    command result_t CPSSetReceive.setReceive[uint8_t channel](uint32_t id, uint32_t mask) {
        if (call CANReceive.setReceive[channel](id, mask)) {
            if (channel == 3)
                if (mask != CAN_DEFAULT_MASK)
                    call Leds.yellowOff();
            call CANReceive.setReceive[channel + 7](id, mask);


Tarjeta de crédito Yahoo! de Banco Supervielle. Solicitá tu nueva Tarjeta de crédito. De tu PC directo a tu casa. 
Visitá www.tuprimeratarjeta.com.ar <http://www.tuprimeratarjeta.com.ar/> 


Yahoo! Encuentros
Ahora encontrar pareja es mucho más fácil, probá el nuevo Yahoo! Encuentros.
Visitá http://yahoo.cupidovirtual.com/servlet/NewRegistration

More information about the Tinyos-help mailing list