为什么没有明确的 SREG RISC 指令?

adr*_*stn 1 assembly avr status-register

我想知道为什么 Atmel RISC 没有针对状态寄存器的“全部清除”指令,而只有像 CLN 和 CLS 这样的个别标志清除指导员。强迫程序员单独明确地清除每一位并避免粗心大意是一件安全的事情吗?

[编辑] 询问是因为我正在检查各种指令对某个类的状态寄存器的影响,并且当我意识到这样的指令不存在时,我正在寻找一条完全重置 SREG 的指令

Pet*_*des 5

强迫程序员单独明确地清除每一位并避免粗心大意是一件安全的事情吗?

不,只是不值得为此提供特殊说明。请注意,SREG 包括中断启用/禁用位和条件代码,我想您很少需要同时清除它们。

(还有 Transfer 标志,即使像cmpand这样的指令也不会修改sub,仅用于bst/bld和相应的分支)。

您不必按顺序运行clz/ cln/ ... ,您最多需要 2 条指令。由于此特定操作并不常见或通常没有用,因此大多数 ISA 不会费心为其提供说明。

仅涵盖条件代码(不是 I 和 T),您可以使用
ldi r16, 1/ 使用subi r16, 02 条指令来完成:无进位,无溢出,无半进位,结果非零,结果非负。 subi reg,0用于清除具有任何非负寄存器值的所有条件代码,因此您通常可以避免额外的ldi.

 cp  r16,r16       ; clears all condition codes except Z=1. (I and T unmodified)
 clz               ; Z=0
Run Code Online (Sandbox Code Playgroud)

第二种方式无需修改任何其他寄存器即可完成。(andi/or保留一些未设置的条件代码,但像 add/sub/compare ( cp)这样的指令将它们全部写入。)任何减去自身的数字都是 0,没有进位、溢出或任何东西。 cp就像 asub不修改其目的地。


一些 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
Run Code Online (Sandbox Code Playgroud)

  • @adrwstn:“sts”是一条 4 字节(2 字)指令,显然并非在每个 AVR 上都可用。正如我在回答中所说,更短又更小(更快)。(删除了我的第一条评论;您的第一条评论缺少代码)。 (2认同)