Користувач:Триадресний код
В інформатиці триадресний код [1] (часто скорочено до TAК (TAC англійською) -- це проміжний код, який використовується оптимізувальними компіляторами для допомоги в реалізації перетворень, що покращують код(оптимізацій) . Кожна інструкція TAC має не більше трьох операндів, і зазвичай є поєднанням оператора присвоєння та бінарного оператора. Наприклад, t1 := t2 + t3
. Назва походить від використання трьох операндів у цих операторах, хоча можуть зустрічатися інструкції з меншою кількістю операндів.
Оскільки триадресний код використовують як проміжну мову в компіляторах, операндами напевно будуть не конкретні адреси пам’яті чи регістри процесора, а скоріше символічні адреси, які будуть перетворені у реальні адреси під час розподілу регістрів. Також нерідко імена операндів нумеруються послідовно, оскільки триадресний код як правило генерується компілятором.
Уточненням триадресного коду є A-нормальна форма (ANF).
Існують два можливих варіанти:
x := y op z
, деop
- це бінарна арифметична або логічна операція. Наприклад:x := y + z
(додавання),x := y * z
(множення),x := y and z
(логічне І).x := op y
, деop
- це унарна операція (мінус, заперечення, оператор конвертації). Наприклад:x := -y
(мінус y),x := not y
(заперечення y),x := int(y)
(конвертація в ціле число).
Мають форму x := y
, де значення, яке міститься у змінній y
, копіюється до змінної x
. Це проста операція, що дозволяє копіювати значення однієї змінної в іншу. Наприклад, якщо маємо змінну y
зі значенням 5
, операція x := y
приведе до того, що змінна x
також буде мати значення 5
.
Мають форму "goto L
", де L
- символьний мітка (label) для позначення інструкції або блоку коду. Ці операції використовують для безумовного переходу у місце в програмі, інтерпретуючи символьну мітку як місце призначення переходу.
Мають форму "if x relop y goto L
", де x
та y
- це операнди, relop
- це оператор відношення (наприклад, рівність, нерівність, менше, більше тощо), а L
- символьна мітка (label) вказує на місце в програмі, куди буде виконано перехід у випадку, якщо умова відповідає вказаному відношенню.
Мають форму
param x1
param x2
...
param xn
call p, n
де x1, x2, ..., xn
- це аргументи, які передаються у процедуру p
, а n
- кількість аргументів.
Ці інструкції вказують компілятору, щоб підготував аргументи x1, x2, ..., xn
у відповідному стані для виклику процедури p
(наприклад, зберег дані в регістрах або скопіював у спеціальну буферну зону) і потім здійснив виклик процедури з цими аргументами. При виклику процедури p
з аргументами x1, x2, ..., xn
, виконуються інструкції, які визначені у тілі процедури.
Після виконання процедури, потік виконання повертається до місця після інструкції call
.
Мають форму "return y
", де y
- це значення, що буде повернено із процедури. Значення у
є опціональним.
Мають дві форми x := y[i]
або x[i] := y
.
Мають форму x := &y
. Після операції в змінній x
буде записана адреса змінної y
x := *y
: Зміннаx
отримує значення, на яке вказує вказівникy
*x := y
: Змінює місце знаходження значення змінноїy
, яке вказується вказівникомx
.
У триадресному коді будь-який вираз може бути перетворен на кілька окремих інструкцій. Ці інструкції пізніше легше перекладати на мову асемблера . Також легше виявити спільні підвирази для скорочення коду.
Нижче наведен приклад обчислення рішення для квадратного рівняння. У триадресному коді те ж саме обчислення складається з кількох дрібних обчислень:
# Calculate one solution to the [[Quadratic equation]]. x = (-b + sqrt(b^2 - 4*a*c)) / (2*a) |
t1 := b * b t2 := 4 * a t3 := t2 * c t4 := t1 - t3 t5 := sqrt(t4) t6 := 0 - b t7 := t5 + t6 t8 := 2 * a t9 := t7 / t8 x := t9 |
Трьохадресний код може містити умовні та безумовні переходи, також методи доступу до пам'яті. Він також може містити методи виклику функцій. Таким чином, триадресний код може бути корисним для аналізу потоку керування . У наведеному нижче прикладі на мові схожій до С, цикл зберігає квадрати чисел від 0 до 9:
...
for (i = 0; i < 10; ++i) {
b[i] = i*i;
}
...
|
t1 := 0 ; initialize i L1: if t1 >= 10 goto L2 ; conditional jump t2 := t1 * t1 ; square of i t3 := t1 * 4 ; word-align address t4 := b + t3 ; address to store i*i *t4 := t2 ; store through pointer t1 := t1 + 1 ; increase i goto L1 ; repeat loop L2: |
Здебільшого триадресні коди дуже схожі на асемблерні інструкції, тому цей код використовують в компіляторах.
Триадресний код часто використовують як проміжне представлення коду в різних фазах оптимізації під час компіляції програм. Триадресний код дозволяє компілятору аналізувати код та здійснювати оптимізації, які можуть покращити ефективність вихідного коду.
Триадресний код також можуть використовувати як проміжне представлення коду в фазах генерації коду під час компіляції. Триадресний код дозволяє компілятору генерувати код, що специфічний для цільової платформи, забезпечуючи при цьому правильність та ефективність вихідного коду.
- Проміжна мова
- Комп'ютер зі скороченим набором інструкцій
- SSA
[[Категорія:Статті з прикладами коду мовою C]] [[Категорія:Теорія компіляторів]]
- ↑ V., Aho, Alfred (1986). Compilers, principles, techniques, and tools. Reading, Mass.: Addison-Wesley Pub. Co. с. 466. ISBN 0201100886. OCLC 12285707.