Изменения

Перейти к: навигация, поиск

Выполнение программы

886 байт добавлено, 03:57, 12 июля 2011
Нет описания правки
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);
}
void gint main()
{
int size = 239; for(;;) { f(size); }
}
Для упрощения выполнения, компилятор может посчитать, что функция <tex>f</tex> имеет свойство <tex>inline</tex>, и преобразовать код в следующий: gint main() { int size = 239; for(;;)Возвращаемое функцией значение тоже храниться на стеке, рядом с локальными переменными. { _alloca(size);{{TODO|t=это мы вроде так для простоты считаем, ссылка на правду } }, что, в свою очередь, вызовет переполнение.
==Архив==
{{TODO|t=здесь наверно и надо написать включить в главу про кучу}}
Рассмотрим процесс выделения памяти в куче на примере простой программы:
97
правок

Навигация