Assembly Avr汇编编程:堆栈上的原子分配
我正在研究用于小型C程序的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_
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重新链接