Вопросы относительно указателя базы и указателя стека - PullRequest
1 голос
/ 17 октября 2011

Я пишу отчет для суммирования стека. Если вы нажмете на мой профиль, вы увидите, что я делал это некоторое время. Прямо сейчас у меня есть некоторые проблемы, потому что на GDB это показывает мне нечто иное, чем на визуальной студии.

В результате я не слишком уверен в своем понимании базового указателя и указателя стека, и я надеюсь, что кто-то может привести меня в правильном направлении, если я ошибаюсь.

Для компьютера с архитектурой x86 стек обычно имеет тенденцию к снижению (с более высокого адреса памяти на более низкий).

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

  1. Как правило, при входе каждого вызова функции в текущем местоположении esp создается стек, и это то, что мы назвали «вершиной стека». Это правильно?

  2. Когда старый ebp помещается в стек, он помещается туда, где был впервые указан esp?

  3. После этого esp опустится вниз, чтобы указать на пустую ячейку памяти, это правильно?

  4. Наконец, esp всегда меняется, перемещаясь вниз, указывая на следующий доступный объем памяти. Это правильно?

  5. ESP перемещается на байт или на 4 байта вниз?

Я знаю, что есть много вопросов. Но спасибо за ваше время!


Спасибо за ответ, сэр!

@ iSciurus

Я запутался, как все определяют esp, указывая на самую последнюю запись, которая была помещена в стек.

Для x86, поскольку стек растет вниз, по вашему объяснению, esp сначала укажет на самый низкий адрес стека. Когда я смотрю на код сборки, у нас есть

   0x080483f4 <+0>: push   %ebp
   0x080483f5 <+1>: mov    %esp,%ebp
   0x080483f7 <+3>: sub    $0x10,%esp

Таким образом, esp уменьшается на 16 байтов. Так что это размер стека этого вызова функции. Локальные переменные появляются сразу после адреса возврата (ebp-4, ebp-8 и т. Д.). Так какова общая цель ESP здесь? Из того, что я понимаю, переполнение стека происходит, когда мы пытаемся получить доступ к адресу, который меньше этого.

Последнее: когда мы говорим о вершине стека, мы ссылаемся на самый низкий адрес (для x86).

Это картинка, которую я имею в виду (растет вниз)

[Parameter n          ]
...
[Parameter 2          ]
[Parameter 1          ]
[Return Address       ]   0x002CF744
[Previous EBP         ]   0x002CF740  (current ebp)
[Local Variables      ]   
-- ESP

Извините за эти длинные вопросы. Но я очень ценю вашу помощь.

1 Ответ

1 голос
/ 17 октября 2011
  1. Если быть точным, кадр стека создается в текущем местоположении esp, а не в самом стеке.Стек создается один раз при запуске потока, и каждый поток имеет свой собственный стек, который является просто областью в области памяти процесса.Фрейм стека - это то, что фактически создается в каждой записи функции, и это область внутри стека потоков.

  2. Нет, он помещается на адрес [old_esp - 4] (или [old_rsp - 8] в x64), потому что esp является вершиной стека и указывает на самый низкий используемый адрес.Следующий DWORD (или QWORD) в стеке свободен, и туда помещается ebp.

  3. Да, обычно это делается с помощью sub esp, значение

  4. Нет.Во-первых, esp перемещается вниз, указывая на самый низкий используемый адрес в стеке, а не на следующее доступное пространство.Во-вторых, имейте в виду, что esp может указывать на что угодно, не только на стек: это нормально, пока вы не используете связанные со стеком инстанции, такие как push / pop.

  5. Esp перемещается на машинное словоразмер: в x86 он перемещается на 4 байта, в то время как в x64 он перемещается на 8 байтов.


Общая цель esp почти всегда одинакова: хранить верхнюю частьстек.Все связанные со стеком инструкции, такие как pop / push, используют esp в качестве аргумента.В x86 и ebp, и esp используются для хранения информации о стековом фрейме (нижний и верхний соответственно).Может быть, вы запутались в этой избыточности.Однако в x64 для параметров на основе стека используется только rsp, а rbp - регистр общего назначения.

Что касается переполнения буфера в стеке, они часто происходят, когда код пытается записать выше, чем последний элементмассив (или структура или что-то).Стек растет вниз, но массивы растут вверх.Когда мы пишем выше, мы можем получить доступ к адресу возврата, обработчику SEH, а также внутренним переменным нашего вызывающего абонента.

Да, когда мы говорим top, мы имеем в виду самый низкий адрес.Итак, большинство отладчиков показывают стек в обратном порядке:

-- ESP
[Local Variables      ]
[Previous EBP         ]   0x002CF740  (current ebp)
[Return Address       ]   0x002CF744
[Parameter 1          ]
[Parameter 2          ]
...
[Parameter n          ]

Здесь ESP указывает на значение «выше» всех данных и выглядит больше как «верх».Хотя это все еще самый низкий используемый адрес.

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