我们考虑一个 RISC 处理器,它只有几个命令,如 DBNZ。我正在尝试编写将寄存器 A 的否定写入 B 的代码以及第二个单独的代码,它应该从 B 中减去 A 并将结果放入 C
我不知道该怎么做
我们考虑一个 RISC 处理器,它只有几个命令,如 DBNZ。我正在尝试编写将寄存器 A 的否定写入 B 的代码以及第二个单独的代码,它应该从 B 中减去 A 并将结果放入 C
我不知道该怎么做
作为记录,真正的 RISC 架构(例如 ARM 或 MIPS)比 DBNZ 更丰富。您所设想的通常被指定为 OISC 或 URISC。
顺便说一句,NASM 也无济于事。它只针对现实生活中的 CPU;你的是一个学术模型。但是用高级语言组装一个模拟器是相当微不足道的。我大概可以在一个小时左右用 JavaScript 写一个。
我为其唯一命令假设的语法是:
DBNZ reg[, label]
意思是:
reg = reg - 1
if label is given and reg != 0 then goto label
如果省略 label,则隐式跳转目标只是下一条指令。对我来说,这是一块语法糖,以提高代码的可读性。
分号之后到行尾的所有内容都是注释。标签以冒号结尾。我的代码假定寄存器的大小是有限的,并且整数回绕是悄悄发生的,没有例外。
求反算法很简单:
b=0
while a > 0
a = a-1
b = b-1
在汇编中,条件跳转和减量是一回事。所以它会是这样的:
;Zero out B
BZeroLoop:
DBNZ B, BZeroLoop ; Decrement until it's zero
;Main loop: subtract from A until it's zero, decrementing B on every iteration
NegLoop:
DBNZ B ; Decrement B with no jump
DBNZ A, NegLoop
现在减法。从 A 中减去 B 的算法(即结果保留在 A 寄存器中)如下:
while b != 0
b = b-1
a = a-1
实际上,它与否定中的循环相同,但没有初始归零。您可以将否定视为适当减法的情况 - 具体而言,它是从零减去。
但是我们需要将结果输入 c。用一种不那么发育不良的语言,我们只是分配。但是我们没有任务。可以使用两个否定和一个临时寄存器进行分配。但是我们可以用一个否定来凑合——首先,就地计算 ba,然后将其否定为 c:
while a != 0
a = a-1
b = b-1 ;this reduces b to the value of b-a
c = 0 ; also a loop
while b != 0
b = b-1
c = c-1
或者,在汇编中:
SubLoop: ; B = B-A
DBNZ B
DBNZ A, SubLoop
CZeroLoop: ; C = 0
DBNZ C, CZeroLoop
NegLoop: ; C = C-B
DBNZ C
DBNZ B, NegLoop