Derleyici - Ara Kod Oluşturma

Bir kaynak kodu doğrudan hedef makine koduna çevrilebilir, o zaman neden kaynak kodunu bir ara koda çevirmemiz gerekiyor ki bu daha sonra hedef koduna çevrilir? Bir ara koda neden ihtiyaç duyduğumuzun nedenlerini görelim.

  • Bir derleyici, ara kod oluşturma seçeneğine sahip olmadan kaynak dili hedef makine diline çevirirse, her yeni makine için tam bir yerel derleyici gerekir.

  • Ara kod, tüm derleyiciler için analiz bölümünü aynı tutarak her benzersiz makine için yeni bir tam derleyici ihtiyacını ortadan kaldırır.

  • Derleyicinin ikinci bölümü olan sentez, hedef makineye göre değiştirilir.

  • Ara koda kod optimizasyon teknikleri uygulayarak kod performansını iyileştirmek için kaynak kodu değişikliklerini uygulamak daha kolay hale gelir.

Ara Temsil

Ara kodlar çeşitli şekillerde temsil edilebilir ve kendi yararları vardır.

  • High Level IR- Üst düzey ara kod gösterimi, kaynak dilin kendisine çok yakındır. Kaynak koddan kolayca üretilebilirler ve performansı artırmak için kolayca kod değişiklikleri uygulayabiliriz. Ancak hedef makine optimizasyonu için daha az tercih edilir.

  • Low Level IR - Bu, hedef makineye yakın olduğundan, kayıt ve bellek tahsisi, komut seti seçimi vb. İçin uygundur. Makineye bağlı optimizasyonlar için iyidir.

Ara kod, dile özgü (örneğin, Java için Bayt Kodu) veya dilden bağımsız (üç adresli kod) olabilir.

Üç Adresli Kod

Ara kod üreteci, açıklamalı bir sözdizimi ağacı biçiminde önceki aşaması olan anlamsal çözümleyiciden girdi alır. Sözdizimi ağacı daha sonra doğrusal bir gösterime, örneğin sonek gösterimine dönüştürülebilir. Ara kod, makineden bağımsız kod olma eğilimindedir. Bu nedenle, kod üreteci, kod üretmek için sınırsız sayıda bellek depolamaya (kayıt) sahip olduğunu varsayar.

Örneğin:

a = b + c * d;

Ara kod üreteci bu ifadeyi alt ifadelere bölmeye çalışacak ve ardından ilgili kodu üretecektir.

r1 = c * d;
r2 = b + r1;
a = r2

r hedef programda kayıt olarak kullanılıyor.

Üç adresli bir kod, ifadeyi hesaplamak için en fazla üç adres konumuna sahiptir. Üç adresli bir kod iki biçimde gösterilebilir: dörtlü ve üçlü.

Dörtlü

Dörtlü sunumdaki her talimat dört alana bölünmüştür: operatör, arg1, arg2 ve sonuç. Yukarıdaki örnek, aşağıda dörtlü formatta temsil edilmektedir:

Op arg 1 arg 2 sonuç
* c d r1
+ b r1 r2
+ r2 r1 r3
= r3 a

Üçlü

Üçlü sunumdaki her komutun üç alanı vardır: op, arg1 ve arg2. İlgili alt ifadelerin sonuçları, ifadenin konumu ile gösterilir. Üçlüler, DAG ve sözdizimi ağacıyla benzerliği temsil eder. İfadeleri temsil ederken DAG'ye eşdeğerdirler.

Op arg 1 arg 2
* c d
+ b (0)
+ (1) (0)
= (2)

Sonuçlar konumsal olduğundan ve bir ifadenin sırasını veya konumunu değiştirmek sorunlara neden olabileceğinden, üçlüler optimizasyon sırasında kodun taşınamazlığı sorunuyla karşı karşıyadır.

Dolaylı Üçlüler

Bu temsil, üçlü gösterime göre bir gelişmedir. Sonuçları saklamak için konum yerine işaretçiler kullanır. Bu, optimize edicilerin, optimize edilmiş bir kod üretmek için alt ifadeyi serbestçe yeniden konumlandırmasını sağlar.

Beyannameler

Kullanılmadan önce bir değişken veya prosedürün bildirilmesi gerekir. Beyan, bellekte alan tahsisini ve sembol tablosuna tür ve adın girilmesini içerir. Bir program, hedef makine yapısı göz önünde bulundurularak kodlanabilir ve tasarlanabilir, ancak bir kaynak kodu hedef diline doğru bir şekilde dönüştürmek her zaman mümkün olmayabilir.

Tüm programı bir prosedürler ve alt prosedürler derlemesi olarak ele alarak, prosedüre özgü tüm isimleri bildirmek mümkün hale gelir. Hafıza tahsisi ardışık olarak yapılır ve programda bildirildikleri sırayla hafızaya isimler tahsis edilir. Ofset değişkenini kullanıyoruz ve onu temel adresi ifade eden sıfıra ayarlıyoruz {offset = 0}.

Kaynak programlama dili ve hedef makine mimarisi, adların saklanma biçiminde değişiklik gösterebilir, bu nedenle göreceli adresleme kullanılır. İlk ad bellek konumu 0 {offset = 0} 'den başlayarak bellek tahsis edilirken, daha sonra bildirilen bir sonraki ad, ilkinin yanında belleğe tahsis edilmelidir.

Example:

Bir tamsayı değişkeninin 2 bayt bellek ve bir float değişkeninin 4 bayt bellek atandığı C programlama dili örneğini alıyoruz.

int a;
float b;

Allocation process:
{offset = 0}

   int a;
   id.type = int
   id.width = 2

offset = offset + id.width 
{offset = 2}

   float b;
   id.type = float
   id.width = 4
   
offset = offset + id.width 
{offset = 6}

Bu detayı bir sembol tablosuna girmek için , bir prosedür girişi kullanılabilir. Bu yöntem aşağıdaki yapıya sahip olabilir:

enter(name, type, offset)

Bu prosedür, değişken adı için sembol tablosunda, tipini tipe ve veri alanında göreceli adres ofsetine ayarlanmış bir giriş oluşturmalıdır .