Лекции по построению компилятора на Pascal

       

ТРУСЛИВЫЙ ВЫХОД


Прежде, чем мы заберемся в детали (и потенциальную сложность) преобразования типов, я хотел бы, чтобы вы видели, что существует один супер простой способ решения проблемы: просто переводить каждую переменную в длинное целое во время загрузки!

Для этого достаточно добавить всего одну строку в LoadVar, хотя, если мы не собираемся полностью игнорировать эффективность, она должна ограничиваться проверкой IF. Вот измененная версия:

{---------------------------------------------------------------}

{ Load a Variable to Primary Register }

procedure LoadVar(Name, Typ: char);

begin

   if Typ <> 'L' then

      EmitLn('CLR.L D0');

   Move(Typ, Name + '(PC)', 'D0');

end;

{---------------------------------------------------------------}

 (Обратите внимание, что StoreVar не нуждается в подобном изменении).

Если вы выполните некоторые тесты с этой новой версией, вы обнаружите, что теперь все работает правильно, хотя иногда неэффективно. К примеру, рассмотрим случай a=b (для тех же самых объявлений, что показаны выше). Теперь сгенерированный код становится:



    CLR.L D0

    MOVE.W B(PC),D0

    LEA  A(PC),A0

    MOVE.B D0,(A0)

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

Я должен подчеркнуть, что устанавливая старшие разряды в нуль, мы фактически обрабатываем  числа как целые числа без знака. Если вместо этого мы хотим обрабатывать их как целые числа со знаком (более вероятный случай) мы должны делать расширение знака после загрузки. Просто для того, чтобы обернуть эту часть дискуссии милой красной ленточкой, давайте изменим  LoadVar как показано ниже:

{---------------------------------------------------------------}

{ Load a Variable to Primary Register }

procedure LoadVar(Name, Typ: char);

begin

   if Typ = 'B' then

      EmitLn('CLR.L D0');

   Move(Typ, Name + '(PC)', 'D0');

   if Typ = 'W' then

      EmitLn('EXT.L D0');

end;

{---------------------------------------------------------------}

В этой версии байт обрабатывается как без-знаковое число (как в Паскале и Си) в то время как слово обрабатывается как знаковое.



Содержание раздела







Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий