Рейтинг:
1
Rob Philpott
Я согласен, но это не то, что я вижу (в отладчике).
Например, для пуш/поп еах вот несколько значений ЭСП перед тужиться, прежде чем поп-и после поп:
0x39f7b0
0x39f7ac
0x39f7b0
Именно то, что вы ожидаете, 4-байтовое движение в каждую сторону для 4-байтового регистра. Для push/pop AX я получил:
0x3ffc60
0x3ffc5e
0x3ffc60
Опять же, точно так же, как вы ожидали бы с 2-байтовым движением для 2-байтового регистра. Но когда я делаю это только для Эла, я получаю это:
0x3ef8c8
0x3ef8c4
0x3ef8c6
Таким образом, движение 4 байта для push и 2 байта для pop, после чего Visual Studio полностью расстраивается, потому что стек неправильный.
Patrice T
Тогда он не может справиться с этим совершенно законным кодексом:
_asm { push al; push bl; pop cx; };
Ошибка в процессоре или VS ?
Rob Philpott
Ассемблер, я думаю. Мне просто пришло в голову проверить окно разборки, и оно показывает это:
толкай ал;
000C16A0 push eax
поп ООО;
000C16A3 поп топор
так нажми Аль =&ГТ; нажать eax и поп АЛ =&ГТ; поп-топор. Это VS2015 C++ в блоке asm.
Patrice T
Тогда вы знаете причину :)
Рейтинг:
0
OriginalGriff
Выталкивание значения из пустого стека не обязательно делает что-то "плохое", оно просто извлекает значение по адресу и уменьшает указатель. Только если этот адрес находится вне области памяти для процесса, вы получите сообщение об ошибке. Теоретически вы можете получить проблему от "return 0", как это должно быть с помощью стека для извлечения адреса выхода, и вы удалили его из стека, но есть вероятность, что ваш компилятор не использует машинный код "return", а завершает процесс с помощью системного вызова - я видел, как это делается в обоих направлениях в зависимости от предпочтений авторов компилятора.
Что касается размера, то при добавлении или удалении любого элемента из стека в машинном коде используется одинаковое количество пространства - машинное слово, которое, скорее всего, будет 16, 32 или 64 бита. Если бы это было не так, то стек оказался бы по нечетным адресам, что является плохой идеей по техническим причинам.
Я удивлен, что "push al" вообще работал - машинный код, который он генерирует, почти наверняка будет "push ax", чтобы избежать нечетных адресов.
Rob Philpott
Да, это очень странно, если вы спросите меня. Если я нажму, а потом хлопну EAX, все будет в порядке. Если я толкаю, то поп-топор тоже все в порядке, но когда вы спускаетесь к АЛУ, толчок и поп перемещают указатель стека на разные суммы, ни то, ни другое, чего я ожидал бы. И я не думаю, что это связано с выравниванием слов.
Я здесь валяю дурака, единственное программирование на ассемблере, которым я всерьез занимался, - это на ARM, где процессор-это хорошо организованная вещь красоты, а не какой-то транзисторный эквивалент спальни подростка с X86, нарисованным на двери.
Это компилятор, которого я жалею...
Patrice T
"Я удивлен, что "push al" вообще работал - машинный код, который он генерирует, почти наверняка будет "push ax", чтобы избежать нечетных адресов."
Нет, это устаревшая совместимость, у процессора нет выбора, даже если это потребует дополнительной работы по обработке несогласованных данных.