Куда именно (!) Указывает указатель стека на процессорах x86? К верхнему элементу или прямо за ним?

В некоторых руководствах говорится, что указатель стека указывает на верхний элемент стека:

+-------------+
|    stack    |
+-------------+
| top element |  <-- esp
+-------------+

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

+-------------+
|    stack    |
+-------------+
| top element | 
+-------------+  <-- esp

На этом немецком сайте википедии https://de.wikipedia.org/wiki/Register_(Computer) сказано, что обе версии существуют и что это зависит от архитектуры процессора.

Мой вопрос, как это на x86-процессорах? И зависит ли это также от операционной системы?

1 ответ

Решение

Допустим, вы находитесь в режиме 32b x86, и у вас есть память с адреса от 100 до 200, зарезервированная как стек (нереально, слишком мало, конфликтует с IVT, но подойдет для этого примера). В стеке уже есть некоторые значения, поэтому esp 160

Теперь "верхняя часть значения стека" занимает память по адресам 160, 161, 162 и 163 (четыре байта, потому что в режиме 32b одно значение в стеке имеет размер 32b = 4B), скажем, есть сохраненное значение 0xaabbccdd,

Если вы сейчас делаете push 0x12345678ЦП сначала вычтет 4 из esp -> новый esp = 156; (160-4), И тогда он запишет значение 32b, разбитое в порядке байтов как четыре байта: mem[156] = 0x78, mem[157] = 0x56, mem[158] = 0x34, mem[159] = 0x12,

Теперь, если вы будете выполнять mov eax,[esp], он будет загружать 32-битное значение из адреса 156, что означает, что он будет составлять 32-битное значение из четырех байтов по адресам 156, 157, 158, 159 в dword значение 0x12345678.

Наконец, когда вы будете просматривать память в отладчике после нажатия, просматривая ее из ss:esp адрес, он будет содержать эти байты (гекса):

0000009C:  78 56 34 12 DD CC BB AA ....

(0x9C = 156 = адрес, с которого начинается просмотр памяти). esp указывает на первый байт значения, которое считается "вершиной стека".

Или когда вы переключаете вид памяти для отображения dword Значения, чтобы избежать создания порядка байтов в голове, он покажет:

0000009C:  12345678 AABBCCDD ....
Другие вопросы по тегам