Давайте создадим компилятор!   ::   Креншоу Джек

Страница: 319 из 382

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



{–}

{ Multiply Top of Stack by Primary (Word) }

procedure GenMult;

begin

EmitLn('MULS D7,D0')

end;

{–}

{ Multiply Top of Stack by Primary (Long) }

procedure GenLongMult;

begin

EmitLn('JSR MUL32');

end;

{–}



Исследование кода ниже для PopMul должно убедить вас, что условия втаблице выполнены:



{–}

{ Generate Code to Multiply Primary by Stack }

function PopMul(T1, T2: char): char;

var T: char;

begin

Pop(T1);

T := SameType(T1, T2);

Convert(T, 'W', 'D7');

Convert(T, 'W', 'D0');

if T = 'L' then

GenLongMult

else

GenMult;

if T = 'B' then

PopMul := 'W'

else

PopMul:= 'L';

end;

{–}



Как вы можете видеть, подпрограмма начинается совсем как PopAdd. Два аргумента приводятся к тому же самому типу. Два вызова Convert заботятся о случаях, когда оба операнда – байты. Сами данные переводятся до слова, но подпрограмма помнит тип чтобы назначать корректный тип результату. В заключение мы вызываем одну из двух подпрограмм генерации кода и затем назначаем тип результата. Не слишком сложно, действительно.

Я полагаю, что сейчас вы уже тестируете программу. Попробуйте все комбинации размеров операндов.

ДЕЛЕНИЕ



Случай с делением совсем не так симметричен. У меня также есть для вас некоторые плохие новости:

Все современные 16-разрядные процессоры поддерживают целочисленное деление. Спецификации изготовителей описывают эту операцию как 32 x 16 бит деление, означающее, что вы можете разделить 32-разрядное делимое на 16-разрядный делитель. Вот плохая новость:

Они вам лгут!!!

Если вы не верите в это, попробуйте разделить любое большое 32-разрядное число (это означает, что оно имеет ненулевые биты в старших 16 разрядах) на целое число 1. Вы гарантированно получите исключение переполнения.

|< Пред. 317 318 319 320 321 След. >|

Java книги

Контакты: [email protected]