我正在查看avr-gcc小型C程序的程序集生成代码.以下应该在堆栈上分配一个100字节的本地数组.
extern void foo(char [], int);
void bar()
{
char t[100];
foo(t,100);
}
Run Code Online (Sandbox Code Playgroud)
当然它通过从堆栈指针中减去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
Run Code Online (Sandbox Code Playgroud)
我还不相信恢复状态指令的位置.
为什么在更新SPL后没有完成?
也许保证在(重新)启用中断后,在下一条指令完成之前不会将中断记入账户?