Как локальная переменная хранится в стеке - PullRequest
0 голосов
/ 25 мая 2018

для программы локальные переменные определены и размещены в стеке, но мне просто интересно, порядок определения локальных переменных не совпадает с порядком их использования.Например, в основной функции int abc определяется, как описано, abc размещается в стеке, что означает, что если переменная a находится в нижней части стека, но когда переменная используется первой, как выскочить из стека?Или ebp указывает на место, где все переменные были сохранены?

1 Ответ

0 голосов
/ 25 мая 2018

По сути, внутри функции локальные переменные хранятся в стековом фрейме.Внутри стекового фрейма порядок доступа к переменным может быть случайным.Я рекомендую прочитать это: http://www.cs.uwm.edu/classes/cs315/Bacon/Lecture/HTML/ch10s07.html

Рассмотрим следующий код

int main (void)
{
  int a = 1, b = 2, c = 3;

  c = c + 55;
  a = a + 10;

  return 0;
}

Компилятор может сгенерировать следующий код

main:
.LFB0:
        .cfi_startproc
        push    rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        mov     rbp, rsp
        .cfi_def_cfa_register 6
        mov     DWORD PTR [rbp-4], 1
        mov     DWORD PTR [rbp-8], 2
        mov     DWORD PTR [rbp-12], 3
        add     DWORD PTR [rbp-12], 55
        add     DWORD PTR [rbp-4], 10
        mov     eax, 0
        pop     rbp
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc

Обратите внимание, что переменная a, b и c хранятся в ячейках rbp-4, rbp-8 и rbp-12, поэтому каждая переменная получает 4 байта (в моей системе).Это минус, потому что стек растет вниз, и начало кадра стека этой функции указывается содержимым rbp.

Далее, обратите внимание, что сначала c = c + 55, а затем a = a + 10 не толкаетили всплывающее окно, и просто получите доступ к местоположениям напрямую, используя add DWORD PTR [rbp-12], 55 и add DWORD PTR [rbp-4], 10 соответственно.Компилятор будет знать, где внутри стекового фрейма находятся эти переменные.

Обратите внимание на push rbp до объявления и обращения к переменным.Эта операция сохранила текущее значение rbp (базовый указатель, 64 бита) в кадре стека.Далее rbp обновляется, чтобы получить новое значение, указывающее пределы для этой функции.Теперь в пределах этого ограничения все локальные переменные могут быть сохранены.Также обратите внимание на pop rbp перед возвратом.Это восстанавливает старое значение rbp из стекового кадра, которое было сохранено ранее, так что после ret оно может вернуться к старому состоянию.

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