Почему невозможно вставить байт в стек на Pentium IA-32?

Я пришел к выводу, что вы не можете вставить байт непосредственно в стек Intel Pentium, кто-нибудь может мне это объяснить, пожалуйста?

Причина, которую мне дали, заключается в том, что регистр esp является адресуемым словом (или, как предполагается в нашей модели), и это должен быть "четный адрес". Я бы предположил, что уменьшение значения некоторого 32-разрядного двоичного числа не помешает выравниванию регистра, но, видимо, я не понимаю достаточно.

Я попробовал некоторые тесты NASM и пришел к выводу, что если я объявлю переменную (bite db 123) и перенесу ее в стек, esp будет уменьшен на 4 (что означает, что она выдвинула 32-битную версию?). Но "push byte bite" (извините за выбор имен переменных) приведет к доброй ошибке:

test.asm: 10: ошибка: не поддерживается не 32-битное перемещение ELF

Любые слова мудрости будут высоко оценены в это смутное время. Я студент первого курса, так что извините за мою наивность во всем этом.

4 ответа

Решение

Он основан на том, как был создан стек:

Атрибут address-size сегмента стека определяет размер указателя стека (16, 32 или 64 бита). Атрибут размера операнда текущего сегмента кода определяет величину уменьшения указателя стека (2, 4 или 8 байт).

В не 64-битных режимах: если атрибуты address-size и operand-size равны 32, 32-битный регистр ESP (указатель стека) уменьшается на 4. Если оба атрибута равны 16, 16-битный регистр SP (стек) указатель) уменьшается на 2.

Источник: http://www.intel.com/Assets/PDF/manual/253667.pdf

стр. 4-320 об. 2B

редактировать

Хотелось бы также отметить, что интересное прочтение - это раздел, посвященный стекам в руководстве, который объясняет дальнейшее создание сегмента стека.

http://www.intel.com/Assets/PDF/manual/253665.pdf

Глава 6.2

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

То, что вы хотите сделать, это использовать коды операций поворота битов для поворота через каждую 32-битную ячейку памяти, помещая по 8 бит за раз в регистр до тех пор, пока вы не вернетесь к начальным битовым позициям. теперь у вас должно быть 4 8-битных значения, выровненных рядом в вашем 32-битном регистре. Теперь вставьте это в стек, и все готово.

Указатель стека должен быть (по некоторым причинам оптимизации) выровненным по 4B -> он должен делиться на четыре (и, следовательно, иметь последние 2 бита равными нулю).

Другие вопросы по тегам