![]() |
|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
![]() |
|
Опции темы | Поиск в этой теме |
![]() |
#1 |
Регистрация: 28.10.2011
Сообщений: 5
|
![]()
**
Профиль · PM Рейтинг (т): нет Всем привет! К своему сожалению, увидел, что в этом разделе не очень-то часто постятся, но все же надеюсь, что кто-то откликнется на мою проблему! Я программирую на C++ компилятор C-подобного подмножества языка в программу на ассемблере. Вопрос по последнему. В ассемблере я не крупный специалист, но кое-что понимаю - в институте был курс по нему, вместо сдачи зачета можно было написать на нем резидентный обработчик прерываний, что я с успехом и сделал. Сразу скажу, что та программа, которую я пишу - учебная. Ее должен будет завизировать препод. Я хочу сделать трансляцию в программу, котороую можно будет уже скомпилировать в MASMе и проверить ее консистентность и работоспособность. Сомневаюсь, что препод будет это делать, но код-то просматривать будет, так что желательно сделать все наиболее правдоподобно. Как и в C++, я позволил каждому блоку в коде иметь свой набор локальных переменных. При этом в каждом блоке, разумеется, будут видны не только локальные переменные этого блока, но и объявленные ранее локальные переменные для охватывающих его блоков. То есть, вот код: Код:
Естественно, обратное не работает, то есть в точке кода во внешнем блоке переменные во внутренних блоках не видны. Я, разумеется, решил организовать локальные переменные в стеке и ссылаться на них через bp. То есть, при заходе в каждый блок в bp запоминается значение sp, а сам sp декрементируется на значение, равное общему размеру выделенной под локальные переменные этого блока области стека. Но тут возникает вопрос, очень серьезный: если мы заходим во вложенный блок, то при повторении этой операции предыдущее значение bp теряется, и мы не можем больше ссылаться на перменные в охватывающем блоке, как с этим быть? Нашел в интернете статейку, где расписано, как работать с локальными переменными во вложенных блоках. Там для этой цели используются команды CPU ENTER и LEAVE, написано, что области данных отслеживаются с помощью так называемого дисплея. Такую же статью я нашел у себя в справочнике по ассемблеру, очевидна, та статья была почти целиком с нее списана - даже примеры те же. Но то, что там это описано - это громко сказано. Приводятся снимкм стека после каждого из нескольких вызовов этих команд. Но реального программного примера - нет! Есть только схематичный пример, где эти команды встречаются разок, но нет в нем команд с адресацией переменных в том или ином блоке. Поэтому, как использовать этот самый дисплей, мне совершенно неясно. Работу мне надо сдавать уже к обеду воскресенья, а я застопорился на этой проблеме. Очень надеюсь на Ваши объяснения, примеры кода, ссылки на статьм с реальным кодом - кто чем богат ![]() |
![]() |
![]() |
![]() |
#2 |
Регистрация: 21.03.2011
Сообщений: 5
|
![]()
А если попробовать написать код процедуры обращения к этим переменным и сохранять их в памяти по адресу например. Тогда они теряться небудут и вызвать процедуру легко просто обратившись к ней... Можно даже с помощью меток этого добиться... И с адресацией преременных можно не путаться, в разных блоках процедура будет их сохранять по собственному адресу и обращаться к ним только по нему же...
|
![]() |
![]() |
![]() |
#3 |
Форумчанин
Регистрация: 05.10.2011
Сообщений: 368
|
![]()
команды ENTER и LEAVE тут не помогут. ENTER это тоже самое что и push ebp/mov ebp, esp. а LEAVE это pop ebp.
если я не ошибаюсь то современные компиляторы поступают так: вычисляется максимальное количество локальных переменных используемых в процедуре и в прологе процедуры выделяется место сразу под все. например: Код:
Не стоит будить спящего Бога! (с) Меланхолия Харухи Судзумии
Последний раз редактировалось haruhi; 04.11.2011 в 17:49. |
![]() |
![]() |
![]() |
#4 |
Регистрация: 28.10.2011
Сообщений: 5
|
![]()
2 haruhi:
Я уже использовал предложенный Вами подход, с той только разницей, что у меня для простоты не делается оптимизация хранения переменных, то есть для каждой переменной выделяется индивидуальное место в стеке, без учета того, что у нас могут быть переменные в нескольких последовательных блоках, соответственно, они жрут места больше, чем в Вашем примере. Для кода, который Вы привели, выделяется место для 9 переменных. Неоптимально, конечно, но тут особого блеска и не требуется. Вот если бы я писал для промышленных целей, тогда я бы уже сделал оптимизацию хранения. Касательно ENTER и LEAVE, Вы неправы. ENTER осуществляет далеко не только то, что Вы написали. Она еще сохраняет предыдущее значение BP, поэтому переменные во внешнем блоке адресовать можно без проблем. И для множественной вложенности это хорошо работает. На другом форуме мне привели достаточно хороший и подробный пример использования этих команд. При наличии необходимости, я бы это реализовал. 2 magistr011: Практически Вас не понял. Вы предлагаете для обращения к переменным использовать процедуру? Это же совершенно неоптимально, программа с таким подходом к работе с локальными переменными будет в разы дольше выполняться. 2 All: Как уже упоминалось выше, я использовал другой метод работы с локальными переменными в нескольких вложенных блоках. Как использоватье ENTER и LEAVE и как адресовать переменные, мне объяснили на другом форуме. Вопрос закрыт, наверно. Но если сюда кто-нибудь ляпнет ссылку на хорошую статейку по ENTER и LEAVE, я буду только рад. К сожалению, сам в инете ничего хорошего и подробного не нашел. В том же примере, что мне привели на другом форуме, для меня не все кристально ясно. А как знать, может, эта техника мне и пригодится в дальнейшем... |
![]() |
![]() |
![]() |
#5 | |
добрый няша
Старожил
Регистрация: 29.10.2006
Сообщений: 4,804
|
![]()
ENTER/LEAVE это уже прошлое. не знаю как насчёт LEAVE, но ENTER это точно атавизм. инструкция ENTER imm16, 0 это тоже самое что и
Код:
для ENTER imm16, 1 код будет сложнее. но я ни разу не встречал такой ситуации когда было бы нужно вторым параметром указывать значение больше нуля Цитата:
всем нужно только Код:
Последний раз редактировалось rpy3uH; 04.11.2011 в 21:15. |
|
![]() |
![]() |
![]() |
#6 |
Регистрация: 28.10.2011
Сообщений: 5
|
![]()
Это используется, когда мы входим во вложенный блок, при этом делается возможность адресации кадров всех предыдущих блоков. Второй операнд ENTER - это уровень вложенности блока
|
![]() |
![]() |
![]() |
#7 | |
добрый няша
Старожил
Регистрация: 29.10.2006
Сообщений: 4,804
|
![]() Цитата:
мне надо самому увидеть, я так не поверю. использование вложенных блоков это МЕГА-ЭКЗОТИКА! нормальному программисту они просто не нужны |
|
![]() |
![]() |
![]() |
#8 |
Регистрация: 28.10.2011
Сообщений: 5
|
![]()
ну вот на Исходниках же есть это, в моей аналогичной теме
|
![]() |
![]() |
![]() |
#9 |
добрый няша
Старожил
Регистрация: 29.10.2006
Сообщений: 4,804
|
![]() Код:
|
![]() |
![]() |
![]() |
#10 |
Регистрация: 28.10.2011
Сообщений: 5
|
![]()
Ну другого у меня нет. Но там объяснено, как использовать второй операнд ENTER, примеры есть. И показано, как обращаться к переменным в разных блоках из разных же, опять-таки блоков.
|
![]() |
![]() |
![]() |
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Работа с переменными | Damhurz | PHP | 6 | 13.03.2009 17:35 |
Работа с переменными | Sapsan | Общие вопросы C/C++ | 2 | 24.02.2009 20:02 |
Работа с динамическими переменными | DonLena | Фриланс | 4 | 15.10.2008 18:13 |
Работа с динамическими переменными | DonLena | Паскаль, Turbo Pascal, PascalABC.NET | 1 | 14.10.2008 20:05 |