Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Message

Re: ASM vs. C

2009-01-15 by Don Kinzer

--- In AVR-Chat@yahoogroups.com, David Kelly <dkelly@...> wrote:
> If you read somewhere that its not supposed to be then
> clearly you are reading old documentation.
This misconception may have arisen from something that I tried to 
explain in an earlier post.  What I meant to convey is that the code 
generated for an arbitrary function f() relies on r1 being zero.  
Since an ISR may call an arbitrary function, the code generated for 
an ISR must ensure that r1 is zero before it makes such a call.  
Consequently, since an ISR may be invoked at an arbitrary time 
(particularly when r1 is non-zero as it might be after a MUL 
instruction), the prologue of the generated ISR code needs to save 
r1 on the stack and set it to zero.

Dave's point is that his ISR clearly doesn't call any external 
functions so the saving/setting/restoring of r1 is rather 
pointless.  While that is certainly true, it is also true that if 
this minor inefficiency is intolerable in your application, you can 
always write the ISR in pure assembly language.  This can be done in 
either of two ways.

1) You can use __attribute__((naked)) to tell the compiler not to 
emit any prologue/epilogue code and then use inline assembly 
language in the ISR to produce *all* of the code needed for the ISR 
including the RETI.

2) You can implement the ISR in assembly language in a .S file.

Here is the code for your Timer0 Overflow ISR to put in a .S file.

#include <avr/io.h>

.section .text

.global TIMER0_OVF_vect
TIMER0_OVF_vect:
  sbi ADCSRA, ADSC
  reti

.end

Of course, this code won't assembly for any AVR device which has its 
ADCSRA above address 0x1f.  If you want the code to work for those 
devices, too, you'll have to add some conditionals which might look 
like this:

#define IO(x) _SFR_IO_ADDR(x)

.global TIMER0_OVF_vect
TIMER0_OVF_vect:
#if (IO(ADCSRA) < 0x20)
 sbi IO(ADCSRA), ADSC
#else
#define tmpReg r24
 push tmpReg
 in tmpReg, SREG
 push tmpReg
 lds tmpReg, ADCSRA
 ori tmpReg, _BV(ADSC)
 sts ADCSRA, tmpReg
 pop tmpReg
 out SREG, tmpReg
 pop tmpReg
#undef tmpReg
#endif
  reti

Don Kinzer
ZBasic Microcontrollers
http://www.basic.net

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.