Вопрос

Я хотел бы знать, кто из них отвечает за очистку стека

Предположим, у вас есть функция 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.В каком порядке они помещаются в стек (действительно ли они передаются через стек)?Не имеет значения, пока звонящий и вызываемый абонент согласны!Это условность.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top