Search code examples
assemblyinterruptavr

Avr assembly programming: atomic allocation on the stack


I'm looking at the avr-gcc assembly generated code for small C programs. The following is supposed to allocate a 100 byte local array on the stack.

extern void foo(char [], int);

void bar()
{
  char t[100];
  foo(t,100);
}

and of course it does, by subtracting 100 from the stack pointer.

I understand that, as the avr is a 8 bit machine, changing the 16bit stack pointer takes 2 steps (changing SPH and SPL). Also, it is a good idea to provide some atomicity by disabling interrupts. It is done by the sequence

in r28,__SP_L__
in r29,__SP_H__           ; get SP
subi r28,100              ; new SP in R29:R28 = OLD -100 
sbc r29,__zero_reg__
in __tmp_reg__,__SREG__   ; save status to r0
cli                       ; disable interrupts
out __SP_H__,r29          ; update SPH
out __SREG__,__tmp_reg__  ; restore status   -- why here ?
out __SP_L__,r28          ; update SPL

what I'm not convinced yet is the position of the restore status instruction.

Why is it not done after updating SPL ?

Maybe there is a guarantee that after (re)enabling interrupts, no interrupt will be taken into accounts before the next instruction has completed?


Solution

  • It seems your are right.
    I cannot find a definitive source and neither can the guys at Electrical Engineering apparently1.

    The closest we got is this statement from the AVR ISA manual for the sei instruction:

    Sets the Global Interrupt Flag (I) in SREG (Status Register). The instruction following SEI will be executed before any pending interrupts.

    Now, as questioned in the EE site, this may be a feature of the sei instruction itself or it maybe a feature of the architecture itself2.

    If you look at the opcodes sei is actually just bset 7 but no note about pending interrupts is present in the bset page, despite bset 7 acting just like sei.
    So I believe that setting the I-bit in SREG will mask interrupt for one more instruction, whenever you use out or sei.

    More information on the linked question: AVR sei instruction3.


    1 The question linked is identical to your, it contain actual answers not like this fake one.
    2 i.e. it doesn't count how you change SREG.
    3 Re-linked.