【问题标题】:Dynamically allocating array, high level language to assembly MIPS动态分配数组,高级语言到汇编 MIPS
【发布时间】:2018-10-14 09:26:27
【问题描述】:

我需要将 C 高级语言转换为 MIPS 的汇编语言。我被这个难住了。任何帮助表示赞赏,谢谢。

array = new int [10] // dynamically allocating size

让我感到困惑的是“new int”部分,翻阅我的书,我找不到任何东西。

【问题讨论】:

  • new 通常在“堆”上分配,但根据用途,您可以在堆栈上分配数组。在您正在编程的系统中,是否有分配内存的系统调用?

标签: assembly mips


【解决方案1】:

那是 C++ 或 C#,而不是 C。

如果您使用 MARS 或 SPIM,则有一个针对 sbrk 的系统调用,您可以使用它来实现堆分配器。 http://courses.missouristate.edu/kenvollmar/mars/help/syscallhelp.html。如果你不关心以后释放内存,直接使用它:syscall$v0=9 分配$a0 更多字节的堆空间,并返回$v0 中的指针。


但通常你可以只保留一些堆栈空间,如果可以在函数结束时释放它作为拆除该函数堆栈框架的一部分。

在 C++ 以外的一些高级语言中,没有与 allocaint array[10] 等效的方法来创建一个本地数组,其存储范围仅限于函数,因此即使私有临时数组也必须使用与完整数组相同的语法-关于长寿命对象的动态分配。

此类语言的编译器使用escape analysis 来确定对该存储的引用是否可以在函数结束后继续存在。如果没有,可以在堆栈上分配存储。 (但如果它确实逃逸了,它必须在堆上分配,例如使用mallocmmap。)

手动“编译”为 asm 时,您应该自己进行转义分析。如果您不返回指向存储的指针,并且您不将其地址传递给任何持有它的函数,那么它只是您可以并且应该为其保留堆栈空间的暂存空间,而不是调用分配和释放系统调用。

在 MIPS 上,这是 gcc5.4 对简单函数 (source+asm on Godbolt) 所做的:

void foo(void) {
    volatile int scratch[10];  // volatile so it can't optimize away
    scratch[1] = 0;
}

# gcc -O3 -fno-delayed-branch
foo():
        addiu   $sp,$sp,-48   # allocate space
        sw      $0,12($sp)    # store into it from the zero-register
        addiu   $sp,$sp,48    # restore stack pointer
        j       $31           # return
        nop                   # branch-delay slot filled with a NOP

所以 gcc 决定从 $sp + 8 开始从头开始,所以第一个 4 字节元素之后的一个 4 字节元素位于 $sp + 12

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多