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

Assembly Avr汇编编程:堆栈上的原子分配,assembly,interrupt,avr,Assembly,Interrupt,Avr,我正在研究用于小型C程序的AVRCC汇编生成的代码。下面假定在堆栈上分配一个100字节的本地数组 extern void foo(char [], int); void bar() { char t[100]; foo(t,100); } 当然是这样,从堆栈指针中减去100 我知道,由于avr是一台8位机器,更改16位堆栈指针需要两个步骤(更改SPH和SPL)。另外,通过禁用中断来提供一些原子性也是一个好主意。它是按顺序完成的 in r28,__SP_L__ in r29,__SP_

我正在研究用于小型C程序的
AVRCC
汇编生成的代码。下面假定在堆栈上分配一个100字节的本地数组

extern void foo(char [], int);

void bar()
{
  char t[100];
  foo(t,100);
}
当然是这样,从堆栈指针中减去100

我知道,由于avr是一台8位机器,更改16位堆栈指针需要两个步骤(更改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号的人也找不到

我们得到的最接近于
sei
指令的以下语句:

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

现在,正如EE站点所质疑的,这可能是
sei
指令本身的一个特性,也可能是架构本身的一个特性2

如果您查看操作码
sei
实际上只是
bset 7
,但是
bset
页面中没有关于挂起中断的说明,尽管
bset 7
的行为就像
sei
一样
因此,我认为在SREG中设置I位将屏蔽一条以上指令的中断,无论何时使用
out
sei

有关链接问题的更多信息:3


1链接的问题与您的答案相同,它包含实际答案,与此假答案不同。
2即,它不计算您如何更改
SREG


3重新链接。

看来您的回答是对的。
我找不到确切的消息来源,显然1号的人也找不到

我们得到的最接近于
sei
指令的以下语句:

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

现在,正如EE站点所质疑的,这可能是
sei
指令本身的一个特性,也可能是架构本身的一个特性2

如果您查看操作码
sei
实际上只是
bset 7
,但是
bset
页面中没有关于挂起中断的说明,尽管
bset 7
的行为就像
sei
一样
因此,我认为在SREG中设置I位将屏蔽一条以上指令的中断,无论何时使用
out
sei

有关链接问题的更多信息:3


1链接的问题与您的答案相同,它包含实际答案,与此假答案不同。
2即,它不计算您如何更改
SREG

3重新链接