Почему невозможно вставить байт в стек на 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 бита равными нулю).