Анимация
JavaScript
|
Главная Библионтека Соответствующая часть транслятора выглядит следующим образом: begin string label; real (label); print ((newline, X6, "BRN", X6, label)) end Здесь значение Х6 есть строка, содержащая шесть пробелов. Если меткой будет L23, генерируется код BRN L23 что означает < переход к метке L23». 3. Вызов стандартного знака операции Параметрами являются конкретный знак операции, адреса операндов и адрес результата. знак операции может использоваться при вызове элемента внутреннего вариантного предложения для генерации соответствующего кода. Например, если знак операции - II + (сложение двух чисел), код может генерировать так: begin address add1, add2, add3; read ((add1, add2, add3)); convert(add1, 1); convert(add2, 2); convert(add3, 3); print ((newline, X6, "LDX1 0 (1)", newline, X6, "ADX1 0(2)", newline, X6, "STO 1 0(3)")) Допускается, что все адреса базированы в стеке. В результате выдается код LDX 1 0 (1) ADX 1 0 (2) STO 1 0 (3) Первая команда кода PLAN загружает в регистр 1 значение адреса, на который указывает регистр 1. Вторая команда складывает значение, содержащееся в адресе, на который указывает регистр 2, со значением, содержащимся в регистре 1 . Третья команда помещает в память содержимое регистра 1 по адресу, на который указывает регистр 3. Convert также может генерировать какой-либо код. Например, если бы add1 находился в стеке идентификаторов в блоке 1 и имел вид (idstack, 1, 4) то генерировался бы следующий код: LDX 1 DISPLAY + 1 AND 1 4 В результате в регистр 1 сначала загружались бы значение DISPLAY +1 и указатель на начало рамки стека, соответствующий блоку 1 , а затем к нему добавилось бы смещение адреса, и в итоге регистр 1 указывал бы на add1 . Если бы add1 находился в рабочем стеке, в регистр пришлось бы также добавить размеры статических областей, находящихся под областью рабочего стека в рамке 4. JUMPF Параметрами служат метка и адрес времени прогона. Результатом команды является переход к метке, если значение, находящееся в адресе, окажется нулем («ложью»). Соответствующая часть транслятора имеет вид begin string label; address add1 ; read ((label, add1)); convert(add1, 1); print ((newline, X6, "LDX 1 0 (1)", newline, X6, "BZE 1" X2, label)) end При метке L23, кроме вида, полученного от вызова convert, выдается также код LDX 1 0(1) BZE 1 L23 (BZE есть мнемоническое обозначение перехода при нулевом значении): 5. ASSIGN Параметрами являются целое число (представляющее тип или указатель на таблицу видов), исходный адрес S и адрес получателя D. Во время компиляции выполняется действие: begin int m: address add1, add2; read ((m, add1, add2)); convert (add1, 1); convert (add2, 2); scan (m) end Scan генерирует код для переписывания элемента типа m из адреса, на который указывает регистр 1 , по адресу, указываемому регистром 2. Если тип простой, например real или int, то для этого потребуется лишь переписать значения одного или боле последовательных адресов с помощью команды MOVE в коде PLAN. Например, MOVE 1 2 перешлет содержимое двух последовательно расположеннтх адресов, начиная с адреса, на который указывает регистр 1 , в два последовательно расположенных адреса, начиная с адреса, на который указывает регистр 2, причем конечные значения этих регистров не изменятся. Вообще тип может быть структурой или массивом. В случае структуры scan применяется рекурсивно 1 и 2 после обращения с ними. Обработка массива, однако, сложнее. Очевидно, что статическую часть (т. е. описатель) переписывать необходимо, но нужно переписывать и динамическую часть (т. е. элементы самого массива). Для переписывания динамической части в регистры 1 и 2 вызываются scan с соответствующими указателями. Однако прежние значения регистров 1 и 2 не должны быть потеряны (представим, что массив был элементом какой-то структуры), и для хранения их значений, кроме всего прочего, требуется стек. Он должен иметь произвольный размер, так как типы могут быть произвольной сложности. Тем не менее каждая реализация, по-видимому, накладывает свои (произвольные) ограничения на размер этого стека. 11.3. ОПТИМИЗАЦИЯ ОБЪЕКТНОГО КОДА Как отмечалось в гл. 10, компиляторы отличаются по степени оптимизации выдаваемого объектного кода, направленной на то, чтобы программа проходила за возможно более короткое время. Выполнение некоторых видов локальной (< узкой») оптимизации почти всегда оправдано. Опишем кратко такую оптимизацию. Рассмотрим три последовательности объектного кода: 1. ldx1 2 ldx 2 1 После загрузки содержимого регистра 2 в регистр 1, несомненно, последует загрузка содержимого регистра 1 в регистр 2, что будет указываться в следующей же команде. Вторая команда (тем более, что она не имеет метки) явно избыточна и ее можно исключить 2. brn l23 команды без меток Здесь brn обозначает безусловный переход. Ряд команд без меток, которые следует за безусловным переходом, выполнять нельзя и поэтому их можно исключить. 3. brn l2 l2 brn l1 В этом случае тот же результат можно получить, заменив первую команду на brn l1 . Такие виды оптимизации выполняются во время генерации кода. Они легко осуществимы в смысле времени компиляции. Упражнения 11.1 Каковы преимущества и недостатки метода компиляции в код Ассемблера, а не непосредственно в машинный код? 11.2. Напишите алгоритмы трансляции следующих команд промежуточного кода, которые были приведены в гл. 10: 1. MOVE 2. JUMPG 11.3. Какое дополнительное действие придется предпринять процедуре convert при обращении к косвенными адресами? 11.4. Какие осложнения может вызвать передача меток в виде целхх чисел (т.е. 23, а не L23) в командах промежуточного кода? 11.5. В различнхх алгоритмах трансляции команд промежуточного кода появляются описания одних и тех же идентификаторов. Как можно этого избежать? Каковы преимущества и недостатки этого прохода? 11.6. Как вы предполагаете, при каких обстоятельствах транслятор будет генерировать вызовы подпрограмм в коде Ассемблера? 11.7. В результате выполнения процедуры convert в регистр могло бы помещаться значение, а не указатель на это значение. Объясните, почему первый вариант не принят. 11.8. Присвоение в Алголе 68, например, обычно требует просмотра видов. В каких еще случаях может оказаться необходимым просмотр видов? 11.9. Укажите, что может потребоваться для реализации «узких» видов оптимизации, описанных в разд. 11.3? 11.10. Третья оптимизация в разд. 11.3 предполагает, что в двух последовательных командах происходит два безусловных перехода. Какое решение возможно в более общем случае? 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 [ 53 ] 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |