2013-03-02 2 views
2

При написании программ MIPS я слышал, что в целом хорошая практика - сохранить регистры в чистоте, то есть очистить значения регистров до 0 в конце программы. Поэтому мой первый вопрос заключается в том, как/почему это необходимо/хорошая практика?Правильное использование сборки (MIPS): регистры против стека

Во-вторых, Если у нас есть вызов функции с параметрами (p1, p2), хранящимися в $ 4 и $ 5; в конце определения нашей функции, необходимо ли очистить значения в 4 и 5 долларов или лучше оставить их так, как они были в начале вызова функции?

Я также видел примеры толкая параметров в стек, как это:

addi $29, $29, -8 
sw $4, 0($29) 
sw $5, 4($29) 
; At the end of our program: 
addi $29, $29, 8 

Когда и почему это необходимо/хорошая практика?

Наконец, Если мы хотим использовать некоторые константы в нашей программе, скажем, 4 и 1, что лучше держать их на регистрах или в стеке? Например:

lis $8 
.word 4 
lis $9 
.word 1 

И тогда мы можем каким-то образом использовать эти значения для нашей программы и затем очистить их до 0.

Или мы могли бы сохранить их в стеке, перемещая указатель стека туда и обратно. Какой подход лучше?

ответ

2

Во-первых, you usually want to use$zero вместо $0, $v0–$v1 вместо $2–$3 и т.д ... они легче понять (и запомнить), чем простые числа и монтажников также понимают это обозначение, так что нет никаких проблем с этой стороны. Также это абстрагирует ваш код от числа, поэтому, если когда-либо стандартные изменения (например, $ zero больше не $ 0, а $ 256), ваш код все равно будет собран правильно.

В каждой архитектуре ЦП существуют некоторые соглашения о том, как использовать регистры для выполнения вызовов и как вести себя с регистрами внутри функций. Это называется соглашением о звонках . Вы можете увидеть here краткое описание соглашения о вызовах MIPS.

Я слышал, что его вообще хорошая практика, чтобы сохранить регистры чистый т.е. очистить значение регистров 0 в конце программы . Итак, мой первый вопрос - как/почему это необходимо/хорошо? практика?

Я лично никогда не слышал об этой практике, но я не совсем согласен с ней. Лучшей практикой было бы восстановить предыдущие значения до начала программы.

Во-вторых, если у нас есть вызов функции с параметрами (p1, p2), хранящимися в $ 4 и $ 5; в конце нашего определения функции, необходимо ли удалить значения в 4 и 5 долларов или лучше оставить их, как они были на , в начале вызова функции?

Вы должны оставить их так, как они были в начале вызова функции. Для вызывающего абонента нет смысла изменять эти регистры.

Пространство в стеке зарезервировано для $ a0- $ a3, если вызываемому абоненту необходимо сохранить его аргументы, но регистры не сохраняются там вызывающим.

Я также видел примеры нажатия параметров в стек как это. Когда и почему это необходимо/хорошая практика?

Стек, если по определению временное хранилище. Если вы хотите зарезервировать значения регистра (например, вы хотите использовать $ aX или $ sX), вы их помещаете туда. То же самое, чем раньше:

Пространство на стеке резервируется за $ a0- $ a3 в случае вызываемая необходимо сохранить его аргументы

addi $sp, $sp, -8 

Перемещает указатель стека регистр (по соглашению это $ 29). Это резервирует 8 байт в стеке.

sw $a0, 0($sp) 
sw $a1, 4($sp) 

экономит $ a0 к вершине стека и $ a1, как второй в стеке (имейте в виду, что стек растет в сторону более низких адресам). Это заполняет зарезервированное пространство (8 байтов). Это называется протоколом ввода функции .

; At the end of our program: 
; You forgot, and it's important: 
lw $a0, 0($sp) 
lw $a1, 4($sp) 
addi $sp, $sp, 8 

Восстановление восстановленных регистров и возврат указателя стека к исходному значению. Тогда у вызывающего будет свой стек и параметры нетронутыми. И это называется протоколом выхода .

Если мы хотим использовать некоторые константы в нашей программе, скажем, 4 и 1, это лучше держать их на регистрах или в стеке?

Ни то, ни другое. Константы следует использовать в качестве непосредственных операндов:

li $t0, C ; Load 16-bit constant into $t0 
lui $t0, C ; Load upper 16-bit half-word of $t0 
+0

Спасибо! Раньше я, возможно, неправильно понимал концепцию «сохранения регистров без изменений», потому что для большинства из них было 0, и я думал, что идея состоит в том, чтобы очистить их до 0 после нашей программы. Но теперь я вижу, что идея состоит в том, чтобы вернуть их обратно к их первоначальным значениям, если мы их используем. –

Смежные вопросы