Давайте создадим компилятор! :: Креншоу Джек
Страница:
305 из 382
Вот измененная версия:
{–}
{ 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;
{–}
В этой версии байт обрабатывается как беззнаковое число (как в Паскале и Си) в то время как слово обрабатывается как знаковое.
|< Пред. 303 304 305 306 307 След. >|