Основной стек использования - PullRequest
1 голос
/ 09 декабря 2010

Я сейчас изучаю стек (x86). Я знаю, что это куча данных, которая работает по принципу LIFO. Я знаю, что основными операциями в отношении стека являются push (для добавления значения в начало стека) и pop (для удаления значения). ESP - это ссылка на то, где мы сейчас находимся в стеке. Теперь, что я не понимаю:

Пример:

  Push 4
  Push ebx
  Push eax

Приведенные выше инструкции сгенерируют стек следующим образом:

 8 eax <-- ESP
 4 ebx
 0 4

Когда ESP указывает на последнюю добавленную стоимость eax.

Теперь, когда мы расширим эти инструкции с помощью операции pop, мы получим что-то вроде:

 Push 4
 Push ebx
 Pop ebx
 Push eax

Приведенные выше инструкции должны привести (если я прав) к следующему стеку (для первых трех инструкций):

 4 (ebx)
 0 4 <-- ESP

Ebx удаляется из стека, а ESP перемещается вниз на 4 бита. Теперь стек после выполнения всех инструкций:

 4  eax <-- ESP
 0 4

Я надеюсь, что все до здесь правильно, если не комментарии более чем приветствуются ;-) Теперь для инструкции mov edx, [ebx, + 04], начиная с первого стека в этом посте. Является ли результатом этого следующее:

 16 eax
 8 edx <-- ESP
 4 ebx
 0 4

Он будет начинаться с ebx + 4 бита при записи edx, перемещая предыдущее значение (eax) в верхнюю часть, или он заменит eax на edx?

Второй вопрос (более общий), как инициировать, адресовать и удалять массивы в стеке.

Приношу свои извинения за этот длинный вопрос, но я хочу понять (основы) стека. Спасибо.

Ответы [ 4 ]

1 голос
/ 09 декабря 2010

Вы примеры и предположения почти точны. Проблема в том, что стек растет. поэтому, если у вас есть адреса 0, 4 и 8, сделайте их вместо 0xF8, 0xF4, 0xF0 и т. д. Если вы в описаниях инструкций в справочном руководстве, вы увидите что-то вроде этого:

PUSH: уменьшает SP на размер операнда (два или четыре байтовых значения) знак расширенный) и передает одно слово из источника в стек верх (SS: SP).

так что если sp (esp) указывает на 0xFC при запуске, а вы

push 4
push ebx
push eax

Тогда стек будет выглядеть так:

0xFC 4
0xF8 (ebx)
0xF4 (eax) <-- esp

Таким образом, доступ к [esp + 4] теперь может иметь больше смысла, так как он получает значение (ebx), а [esp + 8] - это непосредственное значение 4, которое было отправлено.

Так что, если вы разберете или скомпилируете для ассемблера некоторые программы на C с локальными переменными или массивами, вы увидите, что при входе в функцию они вычитают некоторое число из указателя стека, достаточное для охвата всех локальных переменных, тогда [esp + что-то] - это то, как они получают доступ к этой памяти, поэтому инициализация или обнуление, или что-то еще, - это просто вопрос адресации на основе esp в стек.

0 голосов
/ 09 декабря 2010

Вопрос очень неправильный.
push ebx помещает значение из регистра ebx в стек, а не сам регистр.Положив в стек значение ebx, вы не сможете использовать его в качестве основы для адресации.Также нет инструкции (или способа) «вставить» что-то в середину памяти.Это массив, а не динамический список.

Как я уже говорил в комментарии, я думаю, вы не понимаете сами основы сборки.Читайте о модели памяти, регистрах, об основных инструкциях, пишите некоторые программы.

0 голосов
/ 09 декабря 2010

mov edx, [ebx+04] получает данные по адресу es: ebx + 04 и помещает их в edx.Возможно, вы имели в виду mov [ebx+04], edx?В этом случае он будет перезаписывать все по адресу <strong>es</strong>:ebx+4.Если предположить, что es указывает на сегмент стека, а ebx равен esp, то стек будет выглядеть примерно так:

12 edx    <-- [ebx+4]
8  edx    <-- esp = ebx
4  ebx
0  4
0 голосов
/ 09 декабря 2010

Я надеюсь, что все до здесь поправьте, если нет комментариев больше добро пожаловать ;-) Теперь для инструкции mov edx, [ebx, + 04], начиная с Первый стек в этом посте. Это результат этого следующего:

 16 eax
 8 edx <-- ESP
 4 ebx
 0 4

Это начнется в ebx + 4 бита при записи EDX там движется предыдущее значение (Eax) к вершине, или он заменит Eax с EDX?

mov edx, [ebx + 4] переместит значение в [ebx + 4] (это указатель по умолчанию и не будет иметь ничего общего с вашим текущим стеком, если ebx не указывает на стек ( advanced: вероятно, он будет стек, но ссылка на него никак не изменит стек )) на edx. Это отличается от вашего понимания более чем одним способом.

Во-первых, помните, что параметры инструкции mov используются как mov DEST, SRC, а не наоборот.

Во-вторых, эта операция mov только перемещает значение в [ebx + 4] в edx и, как таковая, никак не изменяет указатель стека (здесь ESP). Стек останется неизменным с первого стека, на который вы ссылаетесь здесь. Для наглядности стек останется следующим:

 8 eax <-- ESP
 4 ebx
 0 4

И ни одно из значений в стеке не будет изменено.

Кроме того, я предполагаю, что вы используете 32-битную архитектуру. В этом случае регистры типа eax и т.п. будут 32 бита (4 байта). Пожалуйста, имейте в виду, что это 4 байта, а не биты.

Ваш «второй вопрос» относится к отдельному вопросу здесь, с дополнительной информацией. Удачи!

...