访问寄存器谁的号码存储在另一个寄存器中

Access register who's number is stored in another register

我正在为我的 类 之一开发一个项目,该项目涉及将 C 代码转换为 MIPS 程序集。我在翻译这段代码时遇到问题:

r[extract(ir,15,11)] = aluout;

基本上,r[] 是一个数组,表示 C 中的寄存器。如您所见,它根据 extract 函数的结果来确定访问哪个寄存器。 MIPS中有这样的东西吗?我能想到的唯一方法是获取我将从 extract 子例程中返回的值,并根据所有寄存器号检查它。它的 C 表示形式如下:

regNum = extract(ir, 15, 11);
if (regNum == 1) {
    r[1] = aluout;
} else if (regNum == 2) {
    r[2] = aluout;
} else if (regNum == 3) {
    r[3] = aluout;
} ...

有什么想法吗?这是解决问题的唯一方法吗?

你应该使用自修改代码吗?例如将寄存器号放入即将 运行?

的指令中

这个问题更类似于在 C 中有多个命名变量(var1var2 等)并且必须 return var i 中的值.如果 i 是编译时常量,您可以使用预处理器来完成:

#define expandvar(x) var ## x   // two step process to macro-expand x before concat
#define var(x) expandvar(x)
#define wantvar  4

int foo(void) { return var(wantvar); }
// int foo(constexpr int i) { ... }  // nope

否则你需要一个 switch(),你可以随心所欲地实现它(跳转 table、分支树或其他。)

寄存器没有间接级别,除非您将它们全部存储到内存中,然后在该数组中使用变量偏移量。

实现这一点的一种方法是计算跳转,而不是 table 跳转地址。你会有一系列

# calculate $t0 = set_r0 + reg_num * 8.  (probably using PC as the starting point, rather than actually referencing the address of set_r0)
j $t0     # jump to one of the pairs.

set_r0:
    move $r0, src
    j end
    move $r1, src
    j end
    ...

如果您想检索一个寄存器的值,但破坏所有其他寄存器,

    move $r30, $r31
    move $r29, $r30
    move $r28, $r29
    ...
    move $r0, $r1

在您想要的 reg 被读取的地方跳到这里。