MIPS 编译器局部变量

MIPS Compiler local variables

我正在编写一个转换为 MIPS 程序集的 tinyc 编译器。我对如何实现局部变量处理的问题感到困惑。下面的例子让人很难想出合适的解决方案:

int* funcA() {
    int a = 3;
    return &a;
}

int main() {
    return *(funcA());
}

通常您会在堆栈上创建局部变量。所以在这种情况下 'int a' 将在堆栈上创建。问题是最后我们想要 return 'a' 的地址而不是带有 &a 的值。但是在我们离开 'funcA()' 的那一刻,我们将堆栈重置为旧状态,最后我们 return 的指针不再有效,稍后可以显示为必杀技。

我的第一次尝试是用寄存器来处理所有事情,但是我们用 &-Operator 把它翻译成这样:

    .globl funcA
funcA:
    addiu   $sp, $sp, -4  # save return address
    sw      $ra, ($sp)
    addiu   $sp, $sp, -4  # save the reg we will use for further processing
    sw      $s0, ($sp)
    addiu   $t0, $zero, 3 # $t0 = a and add 3
    la      $s0, ($t0)
    la      $t0, ($s0)
    sw      $t1, ($t0)    # crashes here
    la      $v0, ($t1)    # put the result in $v0
    lw      $s0, ($sp)
    addiu   $sp, $sp, 4   # restore the stack
    lw      $ra, ($sp)
    addiu   $sp, $sp, 4
    jr      $ra           # jump back

它会在标记的行中崩溃,因为目标寄存器没有地址来存储某些东西。一个想法是为每个局部变量创建一个数据段,但这将是一种开销,并且它不适用于递归函数。

有没有人有正确的解决方案来处理局部变量,尤其是当您 return 来自局部变量的地址而不是值时?

感谢任何帮助!

您 运行 遇到的主要问题是您开始使用的示例 C 不是好的代码。尝试在 MIPS 中实现代码的相同问题存在于原始 C 代码中。您永远不应该在函数内创建局部变量并尝试 return 它的地址。该局部变量可以保存在寄存器或堆栈中,其数据可能会被清除。

举个例子,我用C写了这段代码来说明并用mingw32-gcc编译:

int* funcA()
{
    int a = 3;
    return &a;
}

int main (void)
{
    int * myPointer;

    myPointer = funcA();

    return 0;
}

编译器产生此警告:

warning: function returns address of local variable