avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] assembly-c mix and interrupts


From: Paul Stoffregen
Subject: Re: [avr-gcc-list] assembly-c mix and interrupts
Date: Sun, 29 Nov 2009 23:35:35 -0800
User-agent: Thunderbird 2.0.0.23 (X11/20090817)


The issue I am trying to draw attention to is that, in my case, the compiler
is not being conservative so the push/pop of volatile registers must be done
manually.

I experienced this problem with version 4.3.0, I believe provided by an older version of Ubuntu. Version 4.3.2 (as provided by Ubuntu 9.04) fixed the problem. I assume later versions also work, though I have not verified.

Just to be sure, I did a quick test.


// compile with avr-gcc -Wall -mmcu=atmega168 -g -Os -c isr.c
// disassemble with: avr-objdump -d isr.o

#include <avr/io.h>
#include <avr/interrupt.h>

extern void some_random_function(void);

ISR(TIMER0_OVF_vect)
{
       some_random_function();
}


This was the result.


isr.o:     file format elf32-avr

Disassembly of section .text:

00000000 <__vector_16>:
  0:    1f 92           push    r1
  2:    0f 92           push    r0
  4:    0f b6           in    r0, 0x3f    ; 63
  6:    0f 92           push    r0
  8:    11 24           eor    r1, r1
  a:    2f 93           push    r18
  c:    3f 93           push    r19
  e:    4f 93           push    r20
 10:    5f 93           push    r21
 12:    6f 93           push    r22
 14:    7f 93           push    r23
 16:    8f 93           push    r24
 18:    9f 93           push    r25
 1a:    af 93           push    r26
 1c:    bf 93           push    r27
 1e:    ef 93           push    r30
 20:    ff 93           push    r31
 22:    0e 94 00 00     call    0    ; 0x0 <__vector_16>
 26:    ff 91           pop    r31
 28:    ef 91           pop    r30
 2a:    bf 91           pop    r27
 2c:    af 91           pop    r26
 2e:    9f 91           pop    r25
 30:    8f 91           pop    r24
 32:    7f 91           pop    r23
 34:    6f 91           pop    r22
 36:    5f 91           pop    r21
 38:    4f 91           pop    r20
 3a:    3f 91           pop    r19
 3c:    2f 91           pop    r18
 3e:    0f 90           pop    r0
 40:    0f be           out    0x3f, r0    ; 63
 42:    0f 90           pop    r0
 44:    1f 90           pop    r1
 46:    18 95           reti


From this simple test, I believe it should be very clear 4.3.2 is indeed saving all the caller clobbered registers. (also, it appears to be calling itself because the linker has not yet inserted the actual address of "some_random_function") It is horribly inefficient, but looks correct to me.

Maybe you're using version 4.3.0 or something similar? Type "avr-gcc -v" to see the version.


-Paul






// compile with avr-gcc -Wall -mmcu=atmega168 -g -Os -c isr.c
// disassemble with: avr-objdump -d isr.o

#include <avr/io.h>
#include <avr/interrupt.h>

extern void some_random_function(void);

ISR(TIMER0_OVF_vect)
{
        some_random_function();
}

reply via email to

[Prev in Thread] Current Thread [Next in Thread]