我想知道为什么 Atmel RISC 没有针对状态寄存器的"清除所有"指令,而只有像 CLN 和 CLS 这样的单个标记清除讲师。强制程序员单独明确清除每个位并避免粗心大意是安全的吗?
[编辑] 问,因为我正在检查各种指令对类状态寄存器的影响,当我意识到这样的指令不存在时,我正在寻找完全重置 SREG 的指令
强制程序员单独明确清除每个位并避免粗心大意是一件安全的事情吗?
不,只是不值得为此提供特殊说明。请注意,SREG 包括中断启用/禁用位和条件代码,我想您很少需要同时清除两者。
(也是传输标志,即使通过cmp
和sub
等指令也不会修改,仅用于bst
/bld
和相应的分支(。
您不必运行clz
/cln
/...按顺序,您最多需要 2 条指令。 由于此特定操作并不常见或通常有用,因此大多数 ISA 不会费心为其提供说明。
仅涵盖条件代码(不是 I 和 T(,您可以使用ldi r16, 1
/subi r16, 0
在 2 条指令中执行此操作:无进位、无溢出、无半进位、结果为非零、结果为非负数。subi reg,0
可以清除具有任何非负寄存器值的所有条件代码,因此您通常可以避免额外的ldi
。
cp r16,r16 ; clears all condition codes except Z=1. (I and T unmodified)
clz ; Z=0
第二种方式无需修改任何其他寄存器即可完成此操作。 (andi
/or
保留一些未设置的条件代码,但像添加/子/比较(cp
(这样的说明将它们全部写出来。 任何数字减去本身都是 0,没有进位、溢出或任何东西。cp
就像一个sub
,其目的地保持不变。
一些 ISA 提供了一种将其标志寄存器(如果有的话(复制到通用寄存器/从通用寄存器复制的方法,但 AVR 不需要涵盖每个极端情况,因为它的寄存器是内存映射的,包括 SREG。 它是一个RISC CPU,在其16位固定宽度指令格式中更好地利用有限的操作码空间。
在数据空间中,SREG 的地址是0x5F
。 在I/O空间中,它是0x3F
(维基百科(。out
比sts
/lds
短,并且比st
/ld
更方便,具有涉及索引寄存器(X,Y或Z(的寻址模式。
实际上将整个SREG
归零,包括 I 和 T,禁用中断
; R1 = 0 is normally left 0 at all times, one LDI at startup
out $3F, r1 ; SREG = 0
感謝 Jester 指出 SREG 是記憶憶映射的。I/O 编程将在下一堂课中介绍,所以事实证明这实际上是一项非常微不足道的任务,因此没有必要有理由存在这样的指令......
LDI Rd, 0 ; load 0 into GPR
OUT SREG, Rd ; store register data to i/o location