конфигурация стека - PullRequest
       4

конфигурация стека

0 голосов
/ 20 марта 2011

есть конфигурация стека, которая равна

Parameter #N
...
...
Parameter 2   
Parameter 1
Return Address
Old %ebp  
Local Variable 1   
Local Variable 2


I have no idea what `"Old %ebp"` for.

, если %ebp используется для доступа к обратному адресу и параметрам, тогда почему бы %ebp не указать просто

адрес возврата, ачем "Old %ebp"?

это для будущего использования?

мой вопрос

  • Q1.что такое «Старый% ebp» и что это такое?
  • Q2.почему% ebp point Старый% ebp не просто обратный адрес?

Ответы [ 2 ]

3 голосов
/ 20 марта 2011

Регистр ebp (базовый указатель) часто используется при обработке кадров стека (разные «уровни» стека). Хотя указатель стека может меняться в зависимости от того, что вы нажимаете и извлекаете, базовый указатель остается неизменным, пока вы находитесь на одном уровне стека.

Таким образом, вы можете получить все локальные переменные на одной стороне ebp (например, mov ax,[ebp-8]) и все переданные параметры на другой стороне (например, mov ax,[ebp+12]), а также любые другие местоположения которые относятся к ebp, например к коду возврата в некоторых случаях.

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

В этой статье представлен графический обзор того, как он может работать, что я обычно считаю бесценным:

    +------------------+
+-> |   prev-prev EBP  |
|   +------------------+
|   | function param 2 |
|   +------------------+
|   | function param 1 |
|   +------------------+
|   |  return address  |
|   +------------------+
+---|   previous EBP   | <-- current EBP
    +------------------+
    |   local var 1    |
    +------------------+

То, как это работает, заключается в том, что вы передаете параметры функции, а затем просто вызываете эту функцию. Код пролога в начале функции выглядит примерно так:

push ebp           ; save old base pointer.
mov  ebp, esp      ; set new copy.
sub  esp, 16h      ; allocate space for local variables.

, который сохраняет старый ebp и устанавливает новый, указывая на переменные, выдвигаемые вызывающим кодом. Вычитание из указателя стека предназначено для выделения места для местных жителей.

Как указано, это означает, что переданные параметры можно получить с помощью [ebp+N], а локальные - с [ebp-N].

Код эпилога является обратной операцией:

add  esp, 16h      ; forget about locals.
pop  ebp           ; restore previous value
ret                ; return to calling code.

, после чего ebp теперь устанавливается на прежнее значение.

0 голосов
/ 20 марта 2011

%ebp - базовый указатель, все параметры и локальные переменные доступны как смещение от базового указателя. Текущий ebp будет указывать на стек, имеющий old %ebp

например Local Variable 1 is stored at %ebp-4, parameter 1 is stored at %ebp+8.

"Old %ebp" - базовый указатель функции вызывающего абонента, когда вызываемый абонент возвращает базовый указатель старого вызывающего в восстановленный.

Чтобы ответить на второй вопрос, он может это сделать, но это было условием. Часть, которая делает это.

   push %ebp ; save old ebp to stack, this will become old ebp
   mov  %esp, %ebp  ; moving current base pointer to epp

PS: я в основном использую синтаксис nasm, поэтому может быть

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