编写一个高效的 RISC-V 汇编程序,将寄存器 x3 位 x4 写入 注册x7位0,不改变其他x7位。 示例:x3 = 0xdeadbeef、x4 = 0x00000005、x7 = 0xc001cafe。 结果:x7 = 0xc001cafa。 仅使用 RISC-V I 级指令集中的指令(讲义中)。[文本](在此处输入图像描述)
我只是在努力将我的头作为一个整体来解决,如果有人可以一步一步地解释如何解决这个问题,我们将不胜感激
你必须将问题分解为可管理的步骤。
第一个分解是将其写为 C 或伪代码中的表达式。 您将需要一种算法来复制位,尽管非常简单。
以下是我们拥有的一些能力:
我们知道我们可以通过移位来移动位 - 进一步我们可以将输入(例如,
X
)移动恒定量或可变量(例如,Y
) - 所以X >> 2
或X >> Y
。
我们可以通过屏蔽(
and
即&操作)保留一些位并消除其他位。 因此,如果我们想保留某个数字的低两位(例如 Z
),我们可以这样做 Z & 3
。 (请注意,3 是 0...0112,因此 and
与 3 会清除所有高位并仅保留低两位。)
我们可以使用
or
(|
) 操作组合来自两个源的位。 因此,如果我们有两个输入,例如 P
和 Q
,那么 P | Q
代表两者中的所有 1 位。
这些单独的功能中的每一个都可以在大约 1 条装配线中完成。
使用上述功能,我们可以生成一个以您的输入 X、输入位数 Y 和第三个输入 Z 开头的输出。因此,这是使用这些功能创建此表达式的第一步。 请注意,有几个可能的答案,因为我们不必按照上面显示的顺序执行这些功能。
执行此操作的表达式将隔离第一个源中感兴趣的位,将它们移动到适当的位置进行组合(反之亦然),然后隔离第二个源中除感兴趣的位之外的所有位(例如,擦除来自我们想要从第一个输入传输位的第二个源),最后将这些中间体组合成感兴趣的输出。
一旦你有了一个表示你想要看到的结果的表达式,我们可能会将其转换为三地址代码,这是一种将较大的表达式分解为通过变量连接的多个更简单的表达式的方法。
这看起来像几行
TargetN = InputA Operation InputB
。 在三地址代码中,我们总是会为每行的目标选择一个新变量。
三地址代码行将相当简单直接地转换为汇编语言。 汇编的区别在于,我们将使用寄存器名称(在大多数现代体系结构上)而不是变量名称。 此外,另一个区别是,虽然三地址代码将始终使用新的变量名称作为表示复杂表达式的每行代码的赋值目标,但在汇编中我们可以重用不再保存以后感兴趣的值的寄存器。