97
правок
Изменения
Нет описания правки
call f
, где <tex>push</tex> <tex>n</tex> {{---}} команда "положить на стек n". Адрес возврата положится на стек при вызове команды <tex>call</tex>.
===Возвращаемое значение===
Возвращаемое функцией значение тоже храниться на стеке, рядом с локальными переменными.
{{TODO|t=дописать}}
{{TODO|t=это мы вроде так для простоты считаем, ссылка на правду}}
===Конвенции вызова===
====Отличия конвенций====
}
Так как <tex>g</tex> задана конвенция вызова <tex>\_\_stdcall</tex>, после ее вызова вершина стека не будет сдвигаться. Однако, <tex>f</tex> задана конвенция вызова <tex>\_\_cdecl</tex>, поэтому аргумент не удалится со стека при вызове <tex>ret</tex>, и при следующем запросе адреса возврата будет выдан адрес <tex>239</tex>, скорее всего, не являющийся валидным.
==Размещение локальных переменных==
[[Файл:locals.png|right|thumb|200px|Локальные переменные на стеке]]
В функциях также для выполнения промежуточных вычислений, временного хранения данных и пр. могут быть использованы локальные переменные, для выполнения промежуточных вычислений. Эти переменные являются временными и создаются при вызове функции, а удаляются при завершении ее выполнения. Для использования локальных переменных необходимо выделить память. Эта память также тоже выделяется на стеке, прибавлением памяти на нем.
С помощью функции<tex>\_alloca()</tex> можно увеличить размер стека для размещения локальных данных. Так как объем стека ограничен,при использовании этой функции может возникнуть переполнение стека. Простейший пример кода, который вызовет переполнение: void f(int size) { for (;;) { _alloca(size); }в С++ можно прибавлять память на стек. } Так как стек ограничен в своем обьемеОднако, то можно увидеть его переполнение запустив примерно следующий кодможет возникнуть и в менее очевидном случае: void f(int size)
{
_alloca(size);
}
{
}
==Архив==
{{TODO|t=здесь наверно и надо написать включить в главу про кучу}}
Рассмотрим процесс выделения памяти в куче на примере простой программы: