Почему параметры функции помещаются в стек вызовов раньше, чем обратный адрес?
от http://en.wikipedia.org/wiki/Stack_pointer#Structure
Мне интересно, почему обратный адрес функции находится выше параметров для этой функции?
имеет смысл иметь Обратный Адрес толкнул на стопку перед параметры Drawline потому что параметры больше не требуются, когда Обратный Адрес выскочил для возврат к вызывающей функции.
каковы причины предпочтения реализации, показанной на диаграмме выше?
2 ответов
обратный адрес обычно нажимается через call
машинная команда, [которая на родном языке набор команд] в то время как параметры и переменные выталкиваются несколькими машинными командами, которые создает компилятор.
таким образом,обратный адрес-это последнее, что оттолкнуло от абонента, и перед чем-либо [локальные переменные] толкаются вызываемым.
все параметры помещаются перед обратным адресом, потому что переход к фактической функции и вставка обратного адреса в стек выполняется в той же машинной команде.
кроме того, еще одна причина - вызывающий - это тот, кто выделяет пространство в стеке для параметров-он [вызывающий] также должен быть тем, кто его очищает.
причина проста: аргументы функции выталкиваются в стек вызывающей функцией (которая является единственной, которая может это сделать, потому что только она имеет необходимую информацию; в конце концов, весь смысл этого-передать эту информацию вызываемой функции). Обратный адрес передается в стек механизмом вызова функции. Функция называется после вызывающая функция настроила параметры, потому что после вызова это вызываемая функция который выполняется, а не вызывающий.
OK, поэтому теперь вы можете утверждать, что вызывающая функция может поместить параметры дальше используемый в настоящее время стек, и вызываемая функция может просто настроить указатель стека соответственно. Но это не сработает хорошо, потому что в любое время может быть прерывание или сигнал, который подтолкнет текущее состояние в стек, чтобы восстановить позже (я не удивлюсь, если переключатель задач сделает это тоже). Но если вы настройте параметры за пределами текущего стека, эти асинхронные события перезапишут его, и поскольку вы не можете предсказать, когда они произойдут, вы не можете избежать этого (помимо отключения, которое может иметь другие недостатки или даже быть невозможным, в случае переключателя задач). В принципе, все, что выходит за пределы текущего стека, должно считаться изменчивым.
также обратите внимание, что это не зависит от вопроса о том, кто очищает параметры. В принципе, вызываемая функция может позвонить деструкторы аргументов, даже если физически они лежат в стеке вызывающего фрейма. Кроме того, у многих процессоров (включая x86) есть инструкции, которые автоматически выделяют дополнительное пространство над обратным адресом при возврате (например, компиляторы Pascal обычно делали это, потому что в Pascal у вас нет никакой очистки за пределами возвращаемой памяти, и, по крайней мере, для процессоров того времени, было более эффективно очищать эту инструкцию процессора (я понятия не имею, если это все еще верно для современных процессоры.) Однако C не использовал этот механизм из-за списков аргументов переменной длины: для них механизм не был применим, потому что вам нужно было бы знать во время компиляции, сколько дополнительного пространства для выпуска, и K&R C не требовал переадресовывать объявление вариадических функций (C89 делает, но мало, если какие-либо компиляторы используют это из-за совместимости со старым кодом), поэтому вызывающая функция не могла знать, Следует ли очищать аргументы, если это не нужно делать всегда.