Форум программистов, компьютерный форум, киберфорум
Delphi
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
0 / 0 / 1
Регистрация: 09.10.2017
Сообщений: 27
Delphi 6-7

Команды push EBP и pop ECX при вызове процедуры

16.11.2023, 10:59. Показов 1882. Ответов 8

Студворк — интернет-сервис помощи студентам
И здравствуйте!
Недавно стало интересно, какой ассемблерный код генерирует Delphi при компиляции программы, и вот какую странную вещь я обнаружил.
Иногда перед вызовом процедуры без параметров Delphi зачем-то ставит команду "push EBP", а после вызова - команду "pop ECX".
Кто-нибудь знает, зачем она так делает?
Миниатюры
Команды push EBP и pop ECX при вызове процедуры   Команды push EBP и pop ECX при вызове процедуры   Команды push EBP и pop ECX при вызове процедуры  

Команды push EBP и pop ECX при вызове процедуры  
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.11.2023, 10:59
Ответы с готовыми решениями:

Как работают команды pop() и push()
Здравствуйте, подскажите, как работают команды, пожалуйста гугл мне упрямо не хочет дать нужную ссылку. Собираю инфу по частям. В...

Команды, работающие со стеком без push, pop
Необходимо написать последовательность команд, работающие со стеком без использования pop и push c применением базовой индексной адресации...

Сделать так чтобы если вводится push выполнялась функция push, если pop то pop
Помогите пожалуйста с данным вопросом: например у меня есть список и несколько возможных с ним операций (например push - добавить элемент...

8
4187 / 1835 / 220
Регистрация: 06.10.2010
Сообщений: 4,123
24.11.2023, 13:45
Регистр ebp используется для адресации локальных переменных (при соглашении stdcall ещё и параметров). По соглашению о вызове функция не должна его изменять, поэтому производится сохранение регистра в стек.

Типичный код процедуры
Assembler
1
2
3
4
5
6
7
8
push ebp
mov ebp,esp
 
//тут код процедуры
 
mov esp,ebp
pop ebp
ret
pop ecx - это просто выкидывание параметра из стека. Похоже процедура _Test_LocalVars вызывается по соглашению cdecl.
0
0 / 0 / 1
Регистрация: 09.10.2017
Сообщений: 27
24.11.2023, 18:35  [ТС]
1. В Delphi каждая процедура сама сохраняет регистр EBP - сразу после своего вызова - и сама его восстанавливает - непосредственно перед завершением своей работы.
2. В данном случае, перед вызовом процедуры _Test_LocalVars Delphi просто резервирует место в стеке. Зачем она это делает - большая загадка.
3. И вообще, непонятно, зачем функция _Test_LocalVars формирует стековый кадр (сохраняет в стеке регистр EBP), ведь у нее нет ни аргументов, ни локальных переменных. Для доступа к локальной переменной родительской функции (т.е. Test_LocalVars_06c) она вполне могла бы использовать формулу [EBP+N], где N - соответствующее смещение этой переменной.
Короче, налицо двойная глупость Delphi.
А соглашение о вызовах процедур по умолчанию - pascal. Я его не менял.
Миниатюры
Команды push EBP и pop ECX при вызове процедуры  
0
4187 / 1835 / 220
Регистрация: 06.10.2010
Сообщений: 4,123
25.11.2023, 15:13
Ещё раз посмотрел скриншоты - там какой-то хак с переменной r_mdData. При обращении к этой переменной генерится код mov eax,[ebp+8].

В итоге если не смотреть на исходный pascal-код можно подумать, что процедура _Test_LocalVars объявлена так:
Delphi
1
2
3
4
procedure _Test_LocalVars(var r_mdData);cdecl;
begin
...
end;
Может исходники не соответствуют бинарникам?
0
0 / 0 / 1
Регистрация: 09.10.2017
Сообщений: 27
25.11.2023, 16:13  [ТС]
Да нет, это не хак. Это странная манера Delphi работать с локальными переменными. Когда компилятору нужно получить доступ к переменным (или аргументам) родительской процедуры, он делает двойное разыменование регистра EBP: при первом разыменовании он получает адрес ячейки в стеке, в которой хранится значение регистра EBP для контекста родительской процедуры; при втором разыменовании компилятор получает доступ уже к самим переменным (аргументам) родительской процедуры. Если нужен доступ к переменным прародительской процедуры (т.е. на два уровня выше), Delphi выполняет тройное разыменование регистра EBP и т.д.
0
2619 / 1630 / 266
Регистрация: 19.02.2010
Сообщений: 4,324
25.11.2023, 18:12
Цитата Сообщение от GSV4 Посмотреть сообщение
И вообще, непонятно, зачем функция _Test_LocalVars формирует стековый кадр (сохраняет в стеке регистр EBP), ведь у нее нет ни аргументов, ни локальных переменных.
Галка Stack frames в настройках проекта, видимо, включена.
1
0 / 0 / 1
Регистрация: 09.10.2017
Сообщений: 27
25.11.2023, 19:03  [ТС]
Галка Stack frames в настройках проекта, видимо, включена.
Эта галка снята (см. скриншот 3 в первом посте), но в справке Delphi написано:

Некоторые инструменты отладки требуют, чтобы фреймы стека генерировались для всех процедур и функций, но в остальном у вас никогда не должно возникнуть необходимости использовать состояние {$W+}.
Миниатюры
Команды push EBP и pop ECX при вызове процедуры  
0
4187 / 1835 / 220
Регистрация: 06.10.2010
Сообщений: 4,123
26.11.2023, 10:41
Цитата Сообщение от GSV4 Посмотреть сообщение
Да нет, это не хак. Это странная манера Delphi работать с локальными переменными.
Извиняюсь - не заметил, что всё это вложено в процедуру Test_LocalVars_06c, подумал, что это глобальная переменная. Тогда получается, что для вложенных функций Delphi передаёт скрытый параметр - указатель на начало блока локальных переменных родительской процедуры по соглашению cdecl?
1
0 / 0 / 1
Регистрация: 09.10.2017
Сообщений: 27
26.11.2023, 19:16  [ТС]
Цитата Сообщение от murderer Посмотреть сообщение
Тогда получается, что для вложенных функций Delphi передаёт скрытый параметр - указатель на начало блока локальных переменных родительской процедуры по соглашению cdecl?
А почему именно по соглашению cdecl? Здесь везде соглашение pascal.

Ну вроде всё прояснилось:
1. Delphi для вложенной процедуры, образно говоря, пробрасывает мост, чтобы та могла получить доступ к ее данным.
2. А то, что при вызове вложенной процедуры регистр EBP сохраняется дважды (сначала перед вызовом процедуры, а потом самой процедурой), так это просто издержки режима отладки: вторая "копия" регистра EBP делается независимо от первой, т.к. используется только для отладки программы.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.11.2023, 19:16
Помогаю со студенческими работами здесь

Какие обращения к памяти осуществляется при выполнении команды LFS EDI, [EBP+4] в защищенном режиме?
Какие обращения к памяти осуществляется при выполнении команды LFS EDI, в защищенном режиме МП Intel x86, если до выполнения команды...

Push, Pop
Вот такое задание: F=Ʃ от 1 до 5 f (Ai) A1=2 Ai+1=Ai+2 Ai=(3*A)+(C/D). Нужно записать эту формулу в ассемблере с помощью Push, Pop...

push и pop
У меня возникла странная проблема. Мы создали сайт на основе системы управления, которой пользовались не один раз. Все сайты нормально...

Функции pop и push
Здравствуйте, есть код, решающий задачу. В нем есть стандартные функции push и pop. Как можно расписать функции подробно pop и push?...

Верна ли реализация push/pop?
Правильный ли у меня ход мыслей при написании кода, на тему реализации стека? #include <stdio.h> #include <stdlib.h> ...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru