Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.10.2011, 19:44   #1
Homez
 
Регистрация: 28.10.2011
Сообщений: 5
По умолчанию Работа с локальными переменными во вложенных блоках

**
Профиль · PM

Рейтинг (т): нет



Всем привет! К своему сожалению, увидел, что в этом разделе не очень-то часто постятся, но все же надеюсь, что кто-то откликнется на мою проблему!

Я программирую на C++ компилятор C-подобного подмножества языка в программу на ассемблере. Вопрос по последнему. В ассемблере я не крупный специалист, но кое-что понимаю - в институте был курс по нему, вместо сдачи зачета можно было написать на нем резидентный обработчик прерываний, что я с успехом и сделал. Сразу скажу, что та программа, которую я пишу - учебная. Ее должен будет завизировать препод. Я хочу сделать трансляцию в программу, котороую можно будет уже скомпилировать в MASMе и проверить ее консистентность и работоспособность. Сомневаюсь, что препод будет это делать, но код-то просматривать будет, так что желательно сделать все наиболее правдоподобно.

Как и в C++, я позволил каждому блоку в коде иметь свой набор локальных переменных. При этом в каждом блоке, разумеется, будут видны не только локальные переменные этого блока, но и объявленные ранее локальные переменные для охватывающих его блоков. То есть, вот код:

Код:
int a = 3;
if (a > 2)
{
   int b = 4;
   int c = a + b;
}
(Привел на всякий случай, мало ли чего) Переменной c во внутреннем блоке присваивается сумма значений переменных двух переменных, одна из которых объявлена в этом же блоке, а другая - во внешнем.

Естественно, обратное не работает, то есть в точке кода во внешнем блоке переменные во внутренних блоках не видны.

Я, разумеется, решил организовать локальные переменные в стеке и ссылаться на них через bp. То есть, при заходе в каждый блок в bp запоминается значение sp, а сам sp декрементируется на значение, равное общему размеру выделенной под локальные переменные этого блока области стека.

Но тут возникает вопрос, очень серьезный: если мы заходим во вложенный блок, то при повторении этой операции предыдущее значение bp теряется, и мы не можем больше ссылаться на перменные в охватывающем блоке, как с этим быть?

Нашел в интернете статейку, где расписано, как работать с локальными переменными во вложенных блоках. Там для этой цели используются команды CPU ENTER и LEAVE, написано, что области данных отслеживаются с помощью так называемого дисплея. Такую же статью я нашел у себя в справочнике по ассемблеру, очевидна, та статья была почти целиком с нее списана - даже примеры те же. Но то, что там это описано - это громко сказано. Приводятся снимкм стека после каждого из нескольких вызовов этих команд. Но реального программного примера - нет! Есть только схематичный пример, где эти команды встречаются разок, но нет в нем команд с адресацией переменных в том или ином блоке. Поэтому, как использовать этот самый дисплей, мне совершенно неясно.

Работу мне надо сдавать уже к обеду воскресенья, а я застопорился на этой проблеме. Очень надеюсь на Ваши объяснения, примеры кода, ссылки на статьм с реальным кодом - кто чем богат Заранее огромное спасибо!
Homez вне форума Ответить с цитированием
Старый 04.11.2011, 17:19   #2
magistr011
 
Регистрация: 21.03.2011
Сообщений: 5
По умолчанию

А если попробовать написать код процедуры обращения к этим переменным и сохранять их в памяти по адресу например. Тогда они теряться небудут и вызвать процедуру легко просто обратившись к ней... Можно даже с помощью меток этого добиться... И с адресацией преременных можно не путаться, в разных блоках процедура будет их сохранять по собственному адресу и обращаться к ним только по нему же...
magistr011 вне форума Ответить с цитированием
Старый 04.11.2011, 17:41   #3
haruhi
Форумчанин
 
Аватар для haruhi
 
Регистрация: 05.10.2011
Сообщений: 368
По умолчанию

команды ENTER и LEAVE тут не помогут. ENTER это тоже самое что и push ebp/mov ebp, esp. а LEAVE это pop ebp.

если я не ошибаюсь то современные компиляторы поступают так: вычисляется максимальное количество локальных переменных используемых в процедуре и в прологе процедуры выделяется место сразу под все.

например:

Код:
int proc()
{
 int x;
 int y;//2 переменные

  if 
  { 
    int z; // 1 переменная
  }

  if 
  { 
    int p1;
    int p2;
    int p3;// 3 переменные
  }
  if 
  { 
    int par1;
    int par2;
    int par3;// 3 переменные
  }
}
в прологе функции будет выделено место под 5 локальных переменных. 2 основные локальные и 3 во вложенных блоках. причём важно что место выделенное под переменные во вложенных блоках равно максимальному количеству переменных в одном вложенном блоке.
Не стоит будить спящего Бога! (с) Меланхолия Харухи Судзумии

Последний раз редактировалось haruhi; 04.11.2011 в 17:49.
haruhi вне форума Ответить с цитированием
Старый 04.11.2011, 18:44   #4
Homez
 
Регистрация: 28.10.2011
Сообщений: 5
По умолчанию

2 haruhi:
Я уже использовал предложенный Вами подход, с той только разницей, что у меня для простоты не делается оптимизация хранения переменных, то есть для каждой переменной выделяется индивидуальное место в стеке, без учета того, что у нас могут быть переменные в нескольких последовательных блоках, соответственно, они жрут места больше, чем в Вашем примере. Для кода, который Вы привели, выделяется место для 9 переменных. Неоптимально, конечно, но тут особого блеска и не требуется. Вот если бы я писал для промышленных целей, тогда я бы уже сделал оптимизацию хранения.

Касательно ENTER и LEAVE, Вы неправы. ENTER осуществляет далеко не только то, что Вы написали. Она еще сохраняет предыдущее значение BP, поэтому переменные во внешнем блоке адресовать можно без проблем. И для множественной вложенности это хорошо работает. На другом форуме мне привели достаточно хороший и подробный пример использования этих команд. При наличии необходимости, я бы это реализовал.

2 magistr011:
Практически Вас не понял. Вы предлагаете для обращения к переменным использовать процедуру? Это же совершенно неоптимально, программа с таким подходом к работе с локальными переменными будет в разы дольше выполняться.

2 All:
Как уже упоминалось выше, я использовал другой метод работы с локальными переменными в нескольких вложенных блоках. Как использоватье ENTER и LEAVE и как адресовать переменные, мне объяснили на другом форуме. Вопрос закрыт, наверно.

Но если сюда кто-нибудь ляпнет ссылку на хорошую статейку по ENTER и LEAVE, я буду только рад. К сожалению, сам в инете ничего хорошего и подробного не нашел. В том же примере, что мне привели на другом форуме, для меня не все кристально ясно. А как знать, может, эта техника мне и пригодится в дальнейшем...
Homez вне форума Ответить с цитированием
Старый 04.11.2011, 21:13   #5
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

ENTER/LEAVE это уже прошлое. не знаю как насчёт LEAVE, но ENTER это точно атавизм. инструкция ENTER imm16, 0 это тоже самое что и
Код:
push ebp
mov ebp, esp
sub esp, imm16
эти три интрукции выполнятся в два раза быстрее чем одна ENTER.

для ENTER imm16, 1 код будет сложнее. но я ни разу не встречал такой ситуации когда было бы нужно вторым параметром указывать значение больше нуля

Цитата:
Сообщение от Homez Посмотреть сообщение
Как использоватье ENTER и LEAVE и как адресовать переменные, мне объяснили на другом форуме.
знаю, на форуме исходников. общепризнанно что ENTER это старьё. работа этой инструкции сложная и вникать с тонкости её работы не имеет никакого смысла. делает она непонятно что и непонятно зачем, при этом её функционалом всё равно никто не пользуется.
всем нужно только

Код:
push ebp
mov ebp, esp
sub esp, imm16
и не надо ничего придумывать и усложнять себе жизнь!

Последний раз редактировалось rpy3uH; 04.11.2011 в 21:15.
rpy3uH вне форума Ответить с цитированием
Старый 04.11.2011, 21:14   #6
Homez
 
Регистрация: 28.10.2011
Сообщений: 5
По умолчанию

Это используется, когда мы входим во вложенный блок, при этом делается возможность адресации кадров всех предыдущих блоков. Второй операнд ENTER - это уровень вложенности блока
Homez вне форума Ответить с цитированием
Старый 04.11.2011, 21:17   #7
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

Цитата:
Сообщение от Homez Посмотреть сообщение
Это используется, когда мы входим во вложенный блок, при этом делается возможность адресации кадров всех предыдущих блоков.
пример программы в студию. или дамп кода процедуры в которой команда ENTER используется со вторым параметром отличным от нуля.
мне надо самому увидеть, я так не поверю.

использование вложенных блоков это МЕГА-ЭКЗОТИКА! нормальному программисту они просто не нужны
rpy3uH вне форума Ответить с цитированием
Старый 04.11.2011, 21:24   #8
Homez
 
Регистрация: 28.10.2011
Сообщений: 5
По умолчанию

ну вот на Исходниках же есть это, в моей аналогичной теме
Homez вне форума Ответить с цитированием
Старый 04.11.2011, 21:47   #9
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

Код:
PROGRAM Sample;
(* ... *)
  PROCEDURE proc1(x: Integer);
   VAR z1: Integer;
   PROCEDURE proc2(VAR a: Real);
    VAR z2: Real;
    FUNCTION func1(x:Integer): Integer;
     VAR z3: Integer;
     FUNCTION func2: Char;
      VAR z4: Char;
     BEGIN
      (* ... *)
     END;
    BEGIN
     (* ... *)
    END;
   BEGIN
    (* ... *)
   END;
  BEGIN
   (* ... *)
  END;
BEGIN
  (* ... *)
END.
вот это? адекватные программисты так не пишут. это просто сферический пример в вакууме, который показывают студентам
rpy3uH вне форума Ответить с цитированием
Старый 04.11.2011, 21:50   #10
Homez
 
Регистрация: 28.10.2011
Сообщений: 5
По умолчанию

Ну другого у меня нет. Но там объяснено, как использовать второй операнд ENTER, примеры есть. И показано, как обращаться к переменным в разных блоках из разных же, опять-таки блоков.
Homez вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с переменными 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