Динамически размещаемый массив, язык высокого уровня для сборки MIPS - PullRequest
0 голосов
/ 14 октября 2018

Мне нужно конвертировать язык высокого уровня C в язык ассемблера для MIPS.Я поставлен в тупик на этом.Любая помощь приветствуется, спасибо.

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

Что меня смущает, так это новая часть int, просматривающая мою книгу, и я ничего не могу найти в ней.

1 Ответ

0 голосов
/ 14 октября 2018

Это C ++ или C #, а не C.

Если вы используете MARS или SPIM, существует системный вызов для sbrk, который вы можете использовать для реализации распределителя кучи.http://courses.missouristate.edu/kenvollmar/mars/help/syscallhelp.html. Если вам не нужно освобождать память позже, просто используйте ее напрямую: syscall с $v0=9 выделяет $a0 больше байтов пространства кучи и возвращает указатель в $v0.


Но часто вы можете просто зарезервировать некоторое место в стеке, если это нормально, чтобы освободить его в конце функции как часть демонтажа стекового фрейма этой функции.

В некоторых языках высокого уровня, кроме C ++, нет эквивалента alloca или int array[10] для создания локального массива с областью хранения, предназначенной только для функции, так что даже частные чистые массивы должны использовать тот же синтаксис, что и полный-на динамическом размещении долгоживущих объектов.

Компилятор для таких языков избегает анализа , чтобы выяснить, может ли ссылка на это хранилище остаться после конца функции.Если нет, хранилище может быть выделено в стеке.(Но если он сбегает, он должен быть размещен в куче, например, с помощью malloc или mmap.)

При «компиляции» в asm вручную, вы должны выполнить анализ escape самостоятельно.Если вы не вернете указатель на хранилище и не передадите его адрес какой-либо функции, которая его удерживает, то это просто пустое место, для которого вы можете и должны зарезервировать место в стеке вместо вызова функции allocate и free.системные вызовы.

В MIPS это то, что gcc5.4 делает для простой функции ( source + asm на 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-байтовый элемент после первого находится в $sp + 12.

...