1 / 1 / 0
Регистрация: 07.10.2023
Сообщений: 11
1

Коррекция стека с помощью RET вместо POP

07.10.2023, 15:49. Показов 778. Ответов 4

Author24 — интернет-сервис помощи студентам
Всем здравствуйте!
Ковыряю ассемблер под Windows, в качестве ассемблера использую MASM32
Вопрос по коррекции стека при выходе из оконной процедуры
В примере простейшего приложения из книги Пирогова при входе в оконную процедуру регистры EBP, EBX, ESI, EDI сохраняются в стек (инструкциями PUSH), а при выходе из неё - извлекаются из стека (инструкциями POP). Я решил сократить программу, и вместо POP использовать RET с коррекцией стека. Но это приводит к аварийному завершению программы.
Было:
Assembler
1
2
3
4
5
6
7
WMCREATE:
    MOV EAX, 0
    POP EBP
    POP EBX
    POP ESI
    POP EDI
    RET 16
Стало:
Assembler
1
2
3
WMCREATE:
    MOV EAX, 0
    RET 32
Ну, вроде бы при удалении 4-х инструкций POP в стеке остается лишние 4 слова, т.е. 16 байт. Вместо прежней коррекции на 16 байт (это аргументы оконной процедуры) делаю коррекцию на 32 байта (аргументы оконной процедуры и сохраненные в стеке четыре регистра). Но программа при запуске завершается аварийно.
Я проверил, при обработке конкретно этого сообщения WM_CREATE никаких действий с регистрами EBP, EBX, ESI и EDI не производится, т.е. никакие API-функции не вызываются управление возвращается с тем же содержимым. На всякий пожарный я даже пробовал при входе сохранять регистры в буферные переменные и перед выходом восстанавливать их (всё с помощью MOV). Но после сборки программы она перестаёт запускаться. Не могу понять, что не так.
Зато даже при замене RET 16 на RET 20 программа запускается нормально:
Assembler
1
2
3
4
5
6
7
WMCREATE:
    MOV EAX, 0
    POP EBP
    POP EBX
    POP ESI
    POP EDI
    RET 20
Не могу понять, что я делаю не так, и что вообще с коррекцией стека в Windows происходит, если даже при неправильной коррекции стека программа запускается нормально.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.10.2023, 15:49
Ответы с готовыми решениями:

С помощью этих функций, а также функции Pop из задания Dynamic12, извлечь из исходного стека пять элементов и вывести их значения
помогите кто может и у кого есть эта програ))) Dynamic13. Дан указатель P1 на вершину стека....

Masm 32, как получить последнее значение записанное в стек с помощью esp, а не с помощью POP
Здравствуйте. В регистр esp вроде должен быть записан адрес последнего, что добавлено в стек. Я...

Реализация своего pop() для стека
#include <iostream> #include <cstdlib> namespace s21 { template <class T> class stack...

Реализация стека процедур Push и Pop
Реализация стека процедур Push и Pop. help

Удалить последний элемент стека (pop). Динамическая память
Нужно сделать процедуру для удаления последнего элемента стека. Сколько ни пытался, не получается....

4
Ушел с форума
Автор FAQ
16276 / 7601 / 1064
Регистрация: 11.11.2010
Сообщений: 13,616
07.10.2023, 16:10 2
BluntCoder,
сохранять EBP, EBX, ESI и EDI в стеке, а потом восстанавливать их из стека нужно лишь в том случае, если в процедуре используются EBP, EBX, ESI и EDI. Не используйте эти регистры, тогда не нужно будет их помещать в стек и извлекать их оттуда. Пользуйтесь глобальными или локальными процедурами
0
1 / 1 / 0
Регистрация: 07.10.2023
Сообщений: 11
07.10.2023, 16:31  [ТС] 3
Ну, вообще-то вопрос не в этом. А в логике работы ассемблера. Что не так? Почему RET 32 не срабатывает так, как ожидается?
А что такое локальные и глобальные процедуры? Имелись в виду переменные?
0
642 / 151 / 60
Регистрация: 08.04.2015
Сообщений: 389
07.10.2023, 16:31 4
Лучший ответ Сообщение было отмечено BluntCoder как решение

Решение

Цитата Сообщение от BluntCoder Посмотреть сообщение
программа при запуске завершается аварийно
ESP до и после вызова у вас один и тот же, но возвращаетесь не туда, откуда был вызов.


Цитата Сообщение от BluntCoder Посмотреть сообщение
при замене RET 16 на RET 20 программа запускается нормально
Возвращаетесь туда, откуда был вызов, но стек нарушен. Поведение программы зависит от того, что происходит после возврата. При определённых обстоятельствах ошибка нарушения стека может не проявиться.
1
1 / 1 / 0
Регистрация: 07.10.2023
Сообщений: 11
07.10.2023, 16:39  [ТС] 5
UnknownSoldier, ыыы, я понял! При вызове CALL в стек кладётся адрес возврата, он и оказывается в стеке после всех параметров, про него-то я и забыл. Спасибо!
0
07.10.2023, 16:39
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.10.2023, 16:39
Помогаю со студенческими работами здесь

Реализовать операции добавления (push) и удаления (pop) элемента из стека
дать стек строковых значений, для реализации используя односвязные списки. Реализовать операции...

Удалить из стека n элементов, начиная с k. Используя pop, push и временный стэк
Доброго времени суток. Имеется класс, описывающий стек на основе односвязного списка с головой....

Создать стек целочисленных значений. Реализовать операции добавления (push) и удаления (pop) элемента из стека
Создать стек целочисленных значений. Реализовать операции добавления (push) и удаления (pop)...

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

Дана вершина A1 стека,содержащего не менее пяти элементов.Включить в класс IntStack функцию Pop (продолжение в описании)
Дана вершина A1 стека, содержащего не менее пяти элементов. Включить в класс IntStack функцию Pop...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru