首页 文章

Avr汇编编程:堆栈上的原子分配

提问于
浏览
0

我正在查看小型C程序的 avr-gcc 程序集生成代码 . 以下应该在堆栈上分配一个100字节的本地数组 .

extern void foo(char [], int);

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

当然它通过从堆栈指针中减去100来实现 .

据我所知,由于avr是8位机器,更改16位堆栈指针需要2个步骤(更改SPH和SPL) . 此外,通过禁用中断来提供一些原子性是个好主意 . 它由序列完成

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

我还不相信恢复状态指令的位置 .

为什么在更新SPL后没有完成?

也许保证在(重新)启用中断后,在下一条指令完成之前不会将中断记入账户?

1 回答

  • 5

    看来你是对的 .
    我找不到一个明确的来源,而且Electrical Engineering的人们也不能找到它 .

    我们得到的最接近的是来自AVR ISA manualsei 指令的声明:

    设置SREG(状态寄存器)中的全局中断标志(I) . SEI之后的指令将在任何挂起中断之前执行 .

    现在,正如EE网站中所提出的那样,这可能是 sei 指令本身的一个特征,或者它可能是架构本身的一个特征2 .

    如果您查看操作码 sei 实际上只是 bset 7 但是 bset 页面中没有关于待处理中断的注释,尽管 bset 7 就像 sei 一样 .
    所以我相信无论何时使用 outsei ,在SREG中设置I位都会屏蔽中断一条指令 .

    有关链接问题的更多信息:AVR sei instruction 3 .


    1链接的问题与您的相同,它包含的实际答案不像这个假的答案 .
    2即它不计算你如何改变 SREG .
    3重新连结 .

相关问题