为什么没有明确的SREG RISC指令?
Why isn't there a clear SREG RISC instruction?
我想知道为什么 Atmel RISC 没有针对状态寄存器的“全部清除”指令,而只有像 CLN 和 CLS 这样的个别标志清除指令。强制程序员单独显式清除每个位并避免粗心是安全的事情?
[edit] 问是因为我正在检查各种指令对 class 的状态寄存器的影响,我正在寻找一条完全重置 SREG 的指令,当我意识到这样的指令不存在时
感谢 Jester 指出 SREG 是内存映射的。 I/O 编程将在下一个 class 中介绍,事实证明这实际上是一项非常微不足道的任务,因此没有理由存在这样的指令...
LDI Rd, 0 ; load 0 into GPR
OUT SREG, Rd ; store register data to i/o location
It is a safety thing to force the programmer to explicitly clear each bit individually and avoid carelessness?
不,只是不值得为此提供特殊说明。请注意,SREG 包括中断 enable/disable 位和条件代码,我想您很少需要同时清除两者。
(还有 Transfer 标志,即使像 cmp
和 sub
这样的指令也不会修改,仅用于 bst
/ bld
和相应的分支)。
您不必按顺序运行 clz
/ cln
/ ...,您最多需要2条指令。由于此特定操作不常见或通常没有用,因此大多数 ISA 都不会费心为其提供指令。
仅涵盖条件代码(不是 I 和 T),您可以使用
在 2 条指令中完成
ldi r16, 1
/ subi r16, 0
:无进位,无溢出,无半进位,结果非零,结果非负。 subi reg,0
用于清除具有任何非负寄存器值的所有条件代码,因此您通常可以避免额外的 ldi
.
cp r16,r16 ; clears all condition codes except Z=1. (I and T unmodified)
clz ; Z=0
第二种方法无需修改任何其他寄存器即可实现。 (andi
/or
leave some condition codes unset, but instructions like add/sub/compare (cp
) 全部写出来。) 任何数字减去它本身都是 0,没有进位、溢出或任何东西。 cp
就像一个 sub
,它的目的地未被修改。
一些 ISA 提供了一种方法来复制它们的标志寄存器(如果它们有的话)to/from 一个通用寄存器,但是 AVR 不需要涵盖所有极端情况,因为它的寄存器是内存映射的,包括SREG。它是 RISC CPU,在其 16 位固定宽度指令格式中更好地使用有限操作码 space。
在Data space, SREG's address is 0x5F
. In I/O space, it's 0x3F
(wikipedia)。 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 F, r1 ; SREG = 0
我想知道为什么 Atmel RISC 没有针对状态寄存器的“全部清除”指令,而只有像 CLN 和 CLS 这样的个别标志清除指令。强制程序员单独显式清除每个位并避免粗心是安全的事情?
[edit] 问是因为我正在检查各种指令对 class 的状态寄存器的影响,我正在寻找一条完全重置 SREG 的指令,当我意识到这样的指令不存在时
感谢 Jester 指出 SREG 是内存映射的。 I/O 编程将在下一个 class 中介绍,事实证明这实际上是一项非常微不足道的任务,因此没有理由存在这样的指令...
LDI Rd, 0 ; load 0 into GPR
OUT SREG, Rd ; store register data to i/o location
It is a safety thing to force the programmer to explicitly clear each bit individually and avoid carelessness?
不,只是不值得为此提供特殊说明。请注意,SREG 包括中断 enable/disable 位和条件代码,我想您很少需要同时清除两者。
(还有 Transfer 标志,即使像 cmp
和 sub
这样的指令也不会修改,仅用于 bst
/ bld
和相应的分支)。
您不必按顺序运行 clz
/ cln
/ ...,您最多需要2条指令。由于此特定操作不常见或通常没有用,因此大多数 ISA 都不会费心为其提供指令。
仅涵盖条件代码(不是 I 和 T),您可以使用
在 2 条指令中完成
ldi r16, 1
/ subi r16, 0
:无进位,无溢出,无半进位,结果非零,结果非负。 subi reg,0
用于清除具有任何非负寄存器值的所有条件代码,因此您通常可以避免额外的 ldi
.
cp r16,r16 ; clears all condition codes except Z=1. (I and T unmodified)
clz ; Z=0
第二种方法无需修改任何其他寄存器即可实现。 (andi
/or
leave some condition codes unset, but instructions like add/sub/compare (cp
) 全部写出来。) 任何数字减去它本身都是 0,没有进位、溢出或任何东西。 cp
就像一个 sub
,它的目的地未被修改。
一些 ISA 提供了一种方法来复制它们的标志寄存器(如果它们有的话)to/from 一个通用寄存器,但是 AVR 不需要涵盖所有极端情况,因为它的寄存器是内存映射的,包括SREG。它是 RISC CPU,在其 16 位固定宽度指令格式中更好地使用有限操作码 space。
在Data space, SREG's address is 0x5F
. In I/O space, it's 0x3F
(wikipedia)。 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 F, r1 ; SREG = 0