Как получить доступ к локальным переменным функции из стека? - PullRequest
8 голосов
/ 12 февраля 2012

С http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/

Вот последовательность шагов, которая выполняется, когда функция называется:

  1. Адрес инструкции после вызова функции помещается в стек. Вот как процессор запоминает, куда идти после функция возвращает.
  2. В стеке предусмотрено место для типа возврата функции. Пока это просто заполнитель.
  3. Процессор переходит к коду функции.
  4. Текущая вершина стека хранится в специальном указателе, называемом фреймом стека.
  5. Все, что добавляется в стек после этой точки, считается «локальным» для функции.
  6. Все аргументы функции помещаются в стек.
  7. Инструкции внутри функции начинают выполняться.
  8. Локальные переменные помещаются в стек по мере их определения.

Я не уверен, как работает пункт # 6. Если все аргументы функции размещены в стеке, как они доступны?

Если, например, есть три аргумента a, b и c и они помещаются в стек следующим образом: top

| a |
| b |
| c |
|   |
 ...
|___|

Что теперь происходит, когда функция хочет получить доступ к c? a и b выскочили?

Ответы [ 3 ]

14 голосов
/ 12 февраля 2012

Стек представляет собой метафорический стек .Помните, это по-прежнему ОЗУ , поэтому вы можете получить доступ к каждому адресу, не выдвигая остатка, если вы знаете, что ищете.

Поскольку размер автоматической переменной известен ввремя компиляции - компилятор помечает offset для каждой переменной, смещение определяется исходя из того, где секция автоматических переменных при запуске стека [или заголовок стека, оба действительны, и конкретная реализация зависит от архитектуры], ион обращается к ним просто: start + offset для смещения каждой переменной.

1 голос
/ 12 февраля 2012

Нет, они не.Указатель стека (обычно реестр esp) указывает на a, esp+8h указывает на b, esp+16h указывает на c и так далее.Нет необходимости вставлять a.

Обратите внимание, что это деталь реализации.Вы не должны беспокоиться об этом.Число, которое я дал, является чисто теоретическим, в некоторых архитектурах нисходящие адреса задаются последним параметрам, в других - наоборот.Нет гарантии, что это произойдет.

РЕДАКТИРОВАТЬ: Мне кажется, что это не очень надежный источник информации.Он говорит о стеке и куче, но это детали реализации, и они могут даже не присутствовать.

В стандарте нет ограничений для того, чтобы что-либо реализовывалось через стек.Например, у меня сгенерирован следующий код:

void foo(int x, int y, int z)
{
01241380  push        ebp  
01241381  mov         ebp,esp 
01241383  sub         esp,0CCh 
01241389  push        ebx  
0124138A  push        esi  
0124138B  push        edi  
0124138C  lea         edi,[ebp-0CCh] 
01241392  mov         ecx,33h 
01241397  mov         eax,0CCCCCCCCh 
0124139C  rep stos    dword ptr es:[edi] 
    int c = x;
0124139E  mov         eax,dword ptr [x] 
012413A1  mov         dword ptr [c],eax 
    c = y;
012413A4  mov         eax,dword ptr [y] 
012413A7  mov         dword ptr [c],eax 
    c = z;
012413AA  mov         eax,dword ptr [z] 
012413AD  mov         dword ptr [c],eax 
}
012413B0  pop         edi  
012413B1  pop         esi  
012413B2  pop         ebx  
012413B3  mov         esp,ebp 
012413B5  pop         ebp  

Итак, видите, там нет стека.Среда выполнения имеет прямой доступ к элементам: dword ptr [x] и т. Д.

0 голосов
/ 12 февраля 2012

Используется указатель стека и относительный адрес для указания c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...