3.2 Механизм выделения локальной памяти под переменные
Известно, что память под локальные
переменные выделяется из системного стека. Рассмотрим сам механизм выделения на
следующем примере: - int Func(int i, int
k)
{
int
l, m;
l=10;
m=i+k;
...
}
Тогда ассемблерный код будет таким:
| _Func |
mov bp,sp |
; взять адрес вершины стека и поместить в индексный регистр |
|
push r1 |
;сдвинуть указатель стека на слово (память под l) |
|
push r1 |
;сдвинуть указатель стека на слово (память под m) |
|
mov r1,10 |
;загрузить в r1 значение 10 |
|
mov [bp-2],r1 |
;записать по адресу первого параметра |
|
mov r1,[bp+4] |
;загрузить в r1 значение параметра i |
|
mov r2,[bp+6] |
;записать по адресу второго параметра |
|
add r1,r2 |
;сложить |
|
mov [bp-4],r1 |
;занести результат по адресу ячейки m |
|
... |
|
|
pull r1 |
;вернуть память, взятую под локальные переменные |
|
pull r1 |
|
|
Return |
;вернуть управление и значение |
Таким образом, память под параметры
выделяется из стека непосредственно перед вызовом, в момент вызова в стек
заносится адрес возврата, затем выделяется память под локальные переменные. При
входе в функцию указатель стека указывает на слово, содержащее адрес возврата.
Также известно, что системный стек растет от старших адресов к младшим, тогда
параметры будут иметь смещение с плюсом, а локальные переменные с минусом.
|