Кто отвечает за очистку?
-
12-09-2019 - |
Вопрос
Я хотел бы знать, кто из них отвечает за очистку стека
Предположим, у вас есть функция fun, скажем, такая:
var = fun(int x, int y, float z, char x);
когда fun
будет вызвана, она попадет в стек вместе с параметрами, затем, когда функция вернется, кто отвечает за очистку стека - сама функция или "var", который будет содержать возвращаемое значение.
Еще одна вещь, кто-нибудь может объяснить концепции соглашений о вызовах?
Решение
соглашение о вызове относится к тому, кто выполняет очистку стека;звонящий или вызываемый абонент.
Соглашения о вызовах могут отличаться в:
- где размещаются параметры и возвращаемые значения (в регистрах;на вызове стек;сочетание того и другого)
- порядок, в котором передаются параметры (или части одного параметра )
- как распределяется задача настройки и очистки вызова функции между вызывающим и получателем вызова.
- какие регистры, которые могут быть использованы непосредственно вызываемый иногда включаться
Архитектуры почти всегда имеют более чем одно возможное соглашение о вызовах.
Другие советы
Вы сами ссылались на ответ: соглашения о вызовах.
Соглашение о вызове похоже на контракт.Это решает следующие вещи:
- Кто отвечает за очистку параметров.
- Как и в каком порядке параметры передаются вызываемой функции.
- Где хранится возвращаемое значение.
Существует множество различных соглашений о вызовах, в зависимости от платформы и среды программирования.Двумя распространенными соглашениями о вызовах на платформах x86 являются:
стандартный вызов
Параметры передаются в стек справа налево.В вызванный функция очищает стек.
cdecl
Параметры передаются в стек справа налево.В зовущий функция очищает стек.
В обоих случаях возвращаемое значение находится в EAX
зарегистрироваться (или ST0
для значений с плавающей запятой)
Многие языки программирования для платформы x86 позволяют указывать соглашение о вызовах, например:
Дельфы
function MyFunc(x: Integer): Integer; stdcall;
Microsoft C/C++
int __stdcall myFunc(int x)
Некоторые примечания по использованию:
При создании простого приложения редко возникает необходимость изменять соглашение о вызовах или знать о нем, но есть два типичных случая, когда вам нужно позаботиться о соглашениях о вызовах:
- При вызове внешних библиотек, например, Win32 API:Вы должны использовать совместимые соглашения о вызовах, иначе стек может быть поврежден.
- При создании встроенного кода на ассемблере:Вы должны знать, в каких регистрах и где в стеке вы находите переменные.
Для получения более подробной информации я рекомендую эти статьи в Википедии:
К тому времени, когда эта строка будет завершена, var сохранит значение, возвращаемое fun(), и любая память в стеке, используемая fun, исчезнет:"толчок", "хлоп" - все аккуратно.
Соглашения о вызовах:все, что организует компилятор, чтобы fun мог выполнять свою работу.Рассмотрим эти параметры x, y, z.В каком порядке они помещаются в стек (действительно ли они передаются через стек)?Не имеет значения, пока звонящий и вызываемый абонент согласны!Это условность.