Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Все_пособие_редактир.doc
Скачиваний:
175
Добавлен:
31.10.2018
Размер:
2.51 Mб
Скачать
    1. Трехадресный код. Типы трехадресных инструкций

Трехадресный код представляет собой последовательность инструкций вида

х := у op z

где х, у и z — имена, константы или временные переменные, генерируемые компилято­ром; ор означает некоторый оператор, например арифметический оператор для работы с числами с фиксированной или плавающей точкой или оператор для работы с логически­ми значениями. Например, вы­ражение исходного языка наподобие х+у*z может быть транслировано в следующую последовательность.

t1 := у * z

t2 := х + t1

Здесь t1 и t2— сгенерированные компилятором временные имена. Использование имен для вычисленных программой промежуточных значений обеспечивает трехадресному коду, в отличие от постфиксной записи, возможность легкого переупорядочения.

Термин "трехадресный код" отражает тот факт, что каждая инст­рукция обычно содержит три адреса — два для операндов и один для результата.

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

  1. Инструкции присвоения вида х := у op z, где ор— бинарная арифметическая или логическая операция.

  2. Инструкция присвоения вида х := ор у, где ор — унарная операция. Основные унарные операции включают унарный минус, логическое отрицание, операторы сдвига и операторы преобразования, которые, например, преобразуют число с фик­сированной точкой в число с плавающей точкой.

  3. Инструкции копирования вида х : = у, в которых значение у присваивается х.

  4. Безусловный переход goto L. После этой инструкции будет выполнена трехадресная инструкция с меткой L.

  5. Условный переход типа if х relop у goto L. Эта инструкция применяет опе­ратор отношения relop (<, >= и т.п.) к х и у, и следующей выполняется инструк­ция с меткой L, если соотношение х relop у верно. В противном случае выпол­няется следующая за условным переходом инструкция.

  1. Индексированные присвоения типа х := y[i] x[i] := у. Первая инструкция присваивает х значение, находящееся в i-й ячейке памяти по отношению к у. Инст­рукция х[i] : = у заносит в i-ю ячейку памяти по отношению к х значение у. В обеих инструкциях х, у и i ссылаются на объекты данных.

  2. Присвоение адресов и указателей вида х : = &у, х : = *у и *х : = у. Первая ин­струкция устанавливает значение х равным положению у в памяти. Предположи­тельно, у представляет собой имя, возможно временное, обозначающее выражение с l-значением типа А [i,j ], а х — имя указателя или временное имя. Таким образом, r-значение х представляет собой значение некоторого объекта. Во второй инструк­ции под у подразумевается указатель или временная переменная, l-значение которой представляет собой местоположение ячейки памяти. В результате l-значение х ста­новится равным содержимому этой ячейки. И наконец, инструкция *х := у уста­навливает l-значение объекта, указываемого х, равным l-значению у.

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