assembly - 为什么没有明确的 SREG RISC 指令?
问题描述
我想知道为什么 Atmel RISC 没有针对状态寄存器的“全部清除”指令,而只有像 CLN 和 CLS 这样的个人标志清除讲师。强制程序员单独显式清除每个位并避免粗心是安全的吗?
[编辑] 问是因为我正在检查各种指令对一个类的状态寄存器的影响,并且当我意识到这样的指令不存在时,我正在寻找一条完全重置 SREG 的指令
解决方案
强制程序员单独显式清除每个位并避免粗心是安全的吗?
不,只是不值得为此提供特殊说明。请注意,SREG 包括中断启用/禁用位和条件代码,我想您很少需要同时清除两者。
(还有 Transfer 标志,即使像cmp
and之类的指令也不会修改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
保留一些未设置的条件代码,但像 add/sub/compare ( cp
) 这样的指令将它们全部写入。)任何数字减去它自己都是 0,没有进位、溢出或任何东西。 cp
就像 asub
保持其目的地不变。
一些 ISA 提供了一种将其标志寄存器(如果有的话)复制到通用寄存器或从通用寄存器复制的方法,但 AVR 不需要涵盖所有极端情况,因为它的寄存器是内存映射的,包括 SREG。它是一个 RISC CPU,在其 16 位固定宽度指令格式中更好地用于有限的操作码空间。
在数据空间中,SREG 的地址是0x5F
。在I/O 空间中,它是0x3F
(维基百科)。 out
比sts
/短,并且比/使用涉及索引寄存器(X、Y 或 Z)的寻址模式lds
更方便。st
ld
要将整体 SREG
归零,包括 I 和 T,禁用中断
; R1 = 0 is normally left 0 at all times, one LDI at startup
out $3F, r1 ; SREG = 0
推荐阅读
- html - 大型网站如何处理布局和/或代码的变化?
- javascript - `setInterval` 中的时间问题
- c# - Blazor 字符串输入绑定列表
- javascript - 味精对象是不可读的信息
- laravel - 在 laravel 中跟踪用户的登录时间
- react-native - 使用本机反应将图像上传到 Firebase 存储
- javascript - Webpack 为少量导入创建单独的 JS 文件
- laravel - 从 DB 中排除私人国家用户 - Laravel 存储库
- c - 如何在具有输入参数无符号 32 位数组的函数中传递结构?
- jq - jq 是否支持多个 -f 选项?