Это 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
.