Buyruk kümesi mimarisi
Komut yapıları > İşlenen sayıları ve komut uzunluğu

Bir bilgisayar mimarisini tanımlamak için en bilindik yöntem her bir komutta yer alan en fazla işlenen sayısını ya da adresini belirlemektir. Bu tek başına komutun uzunluğuna doğrudan etki etmektedir. Güncel mimarilerdeki komutlar iki şekilde biçimlendirilebilir:
Sabit Uzunluk: Alanı boş yere israf eder, ancak komut-seviyesi boru hattı kullanıldığında hızlıdır ve daha iyi performans oluşur.
Değişken Uzunluk: Şifre çözmesi daha karmaşıktır fakat depolama alanını en iyi şekilde kullanılır.
Çoğu zaman, gerçek hayatta uzlaşma, kolay görülebilen ve kod çözümü daha kolay olan bit kalıplarını sağlayan iki-üç komut uzunluğunu kullanmayı gerektirir. Komut uzunluğunu makinedeki sözcük uzunluğuyla karşılaştırmamak lazım. Eğer komut uzunluğu sözcük uzunluğuna eşitse, komutlar ana bellekte saklandıklarında mükemmel bir şekilde hizalanırlar. Komutlar, adreslemeden dolayı daima hizalanmalıdır. Bundan dolayı, bir sözcüğün iki katı, üç katı, yarısı ya da çeyreği büyüklüğündeki komutlar boşa alan israf edebilir. Değişken uzunluktaki komutlar aynı boyutta olmadıklarından hizalanmaları gerekir, bu da yine alan israfına yol açar.
En yaygın komut biçimleri sıfır, bir, iki ya da üç işlenene sahip olanlardır. Mantık ve aritmetik işlemleri genellikle iki işlenene sahiptir, ancak eğer biriktirici (accumulator) varsa işlemler yalnızca bir işlenenle yürütülebilir. Bu yaklaşımı üç işlenene genişletirsek son hedef üçüncü işlenen olacaktır. Ayrıca yığın yapısı kullanılarak sıfır işlenenli komutlar oluşturulabilir. Aşağıdakiler en genel komut biçimleridir:
Sadece işlem kodu (adres yok)
İşlem kodu + 1 Adres (genellikle bir bellek adresi)
İşlem kodu + 2 Adres (genellikle iki yazmaç ya da bir yazmaç bir bellek adresi)
İşlem kodu + 3 Adres (genellikle üç yazmaç ya da yazmaç ve belleğin bileşimi)
Mesela MIPS mimarisinde aşağıdaki komut biçimleri kullanılır:
| 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 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Type |
| Opcode | Opcode | Opcode | Opcode | Opcode | Opcode | rs | rs | rs | rs | rs | rt | rt | rt | rt | rt | rd | rd | rd | rd | rd | shamt | shamt | shamt | shamt | shamt | funct | funct | funct | funct | funct | funct | R-Type |
| Opcode | Opcode | Opcode | Opcode | Opcode | Opcode | rs | rs | rs | rs | rs | rt | rt | rt | rt | rt | immediate | immediate | immediate | immediate | immediate | immediate | immediate | immediate | immediate | immediate | immediate | immediate | immediate | immediate | immediate | immediate | I-Type |
| Opcode | Opcode | Opcode | Opcode | Opcode | Opcode | address | address | address | address | address | address | address | address | address | address | address | address | address | address | address | address | address | address | address | address | address | address | address | address | address | address | J-Type |

Bütün mimariler komut başına işlenen sayısında izin verilen bir sınıra sahiptir. Sıfır, bir, iki ve üç işlenenli komutların çok yaygın olduğunu söylemiştik. Bir, iki ve üç işlenenli komutları anlamak kolaydır, ancak tamamıyla sıfır işlenenli komutlar üzerine yapılmış bir komut kümesi mimarisi bir hayli karmaşıktır.
Toplama gibi, mantık olarak bir ya da iki işlenene ihtiyaç duyan işlemlerin yapılabilmesi için işleneni olmayan makine komutları yığın kullanmaya ihtiyaç duyar. Yığın tabanlı mimari genel amaçlı yazmaçları kullanmak yerine işlenenleri yığının en üstünde saklar ve en üstteki ögeye merkezi işlem biriminin ulaşmasını sağlar. (Makine mimarilerindeki en önemli veri yapılarından biri yığındır. Yığın yapısı karmaşık hesaplamalar sırasında ara değerleri verimli bir şekilde saklar, yordam çağrıldığı anda parametrelerin geçişini verimli bir şekilde sağlar, bununla birlikte yerel blok yapısının korunmasını da sağlar, değişkenlerin ve altyordamların kapsamlarını belirler.)
Yığın tabanlı mimarilerde, birçok komut yalnızca işlem kodlarından oluşur. Bununla birlikte sadece bir işleneni olan özel komutlar da vardır (yığına eleman ekleyen veya yığından eleman çıkaran tipi komutlar). Yığın mimarileri, her biri bir işlenene sahip olan push ve pop komutlarına ihtiyaç duyarlar. Push X komutu, X bellek konumundaki veri değerini yığının üstüne yerleştirir. Pop X komutu, yığının en üstteki ögesini siler ve X bellek konumuna yazar. Belleğe erişme izni sadece bazı komutlara verilir; diğer bütün komutlar yürütme esnasında herhangi bir işlenen için yığını kullanmak zorundadır.
İki işlenene ihtiyaç duyulan işlemlerde, yığının en üstteki iki elemanı kullanılır. Mesela bir ADD komutu çalıştırıldığında, CPU yığının en üstteki iki elemanını alır, ikisini de yığından atar ve yığının en üstüne toplama işleminin sonucunu yerleştirir. Çıkarma işlemi gibi değişmeli olmayan işlemlerde, en üstteki öge bir altındaki ögeden çıkarılır, ikisi de yığından atılır ve yığının en üstüne çıkarma işleminin sonucu yerleştirilir.
Bu yığın organizasyonuna Reverse Polish Notation (RPN) veya postfix gösterimi denir ve uzun aritmetik ifadeler için oldukça etkili ve verimlidir. Postfix gösteriminde, işleç işlenenlerden sonra yer alır. Infix gösteriminde işleç işlenenlerin arasında yer alır, prefix gösteriminde ise işleç işlenenlerden önce gelir:
X Y + postfix (Reverse Polish)
X + Y infix
+ X Y prefix (Polish)
gösterimidir.
Bütün aritmetik ifadelerin bu gösterimleri kullanarak yazılması mümkündür. Fakat, bir yazmaç yığını ile birleştirilmiş postfix gösterimi, aritmetik ifadelerin hesaplanmasında en etkili yoldur. Bazı elektronik hesap makineleri kullanıcıdan ögeleri postfix gösteriminde girmesini ister. Bu hesap makinelerinde biraz alıştırma yapıldığında, iç içe dizilmiş birçok parantez içeren uzun ifadeleri, terimlerin nasıl gruplandığını bile düşünmeden, daha hızlı bir şekilde hesaplamak mümkündür.
(X + Y) x (W - Z) + 2
Denklemi RPN'de yazılırsa aşağıdaki gibi olur:
XY + WZ - x2+
Dikkat edilecek olursa, RPN'de öncelikleri korumak amacıyla kullanılan parantezlere ihtiyaç duyulmaz.
Sıfır, bir, iki ve üç işlenen kavramlarıyla ilgili bir örnek verelim. Her bir kavramı kullanarak, bir aritmetik hesap yapan basit bir program yazalım.
Örnek, aşağıdaki ifadeyi hesaplansın:
Z = (X x Y) + (W x U)
Genelde, üç işlenene izin verildiğinde, en az bir işlenen yazmaç olur ve ilk işlenen genellikle hedef olur. Üç adresli komutları kullanırken, Z'nin hesaplanması için gereken kodu aşağıdaki gibi yazabiliriz:
Mult R1, X, Y
Mult R2, W, U
Add Z, R2, R1
Eğer iki adresli komutlar kullanılıyorsa, bir adres genellikle bir yazmacı ifade eder (iki adresli komutlar iki işlenenin de bellek adresi olmasına pek izin vermez). Diğer işlenen, bir yazmaç ya da bir bellek adresi olabilir. İki adresli komutlar kullanırsak kodumuz aşağıdaki gibi olur:
Load R1, X
Mult R1, Y
Load R2, W
Mult R2, U
Add R1, R2
Store Z, R1
İlk işlenenin hedef mi yoksa kaynak mı olduğunu bilmek önemlidir, burada hedef olduğunu öngörüyoruz. (Bu noktada, Intel çevirici dili ile Motorola çevirici dili arasında geçiş yapmak zorunda kalan programcıların kafası karışabilir. Çünkü Intel çeviricisi ilk işleneni hedef alır, Motorola çeviricisi ise ilk işleneni kaynak alır.)
Tek adresli komutlar kullanıldığında, bir yazmaç (genellikle biriktirici) komutun sonucu için hedef olarak gösterilir. Z'nin hesaplanmasındaki kod aşağıdaki gibi olur:
Load X 
Mult Y 
Store Temp 
Load W 
Mult U 
Add Temp 
Store Z
Komut başına izin verilen işlenen sayısı azaldı, fakat kodu çalıştırmak için gerekli olan komut sayısı arttı. Bu durum, mimari tasarımında tipik bir boşluk ya da zamandan taviz verme örneğidir. Daha kısa komutlar oluşur, fakat programlar uzar.
Sıfır adresli komutlara sahip olan yığın tabanlı bir makinede bu programın ne yaptığını araştıralım şimdi de. Yığın tabanlı mimariler Add, Subt, Mult veya Divide komutları için işlenen kullanmazlar. Bir yığına ve bu yığında pop ve push işlemlerine ihtiyaç duyulur. Yığına erişim gerçekleştiren işlemler, işlenenin yığına eklendiğini ya da yığından çıkarıldığını belirten bir adres alanına sahip olmalıdırlar (diğer bütün işlemler sıfır adreslidir). Push komutu işleneni yığının en üstüne iter. Pop komutu yığının en üstündeki elemanı yakalar ve işlenene yerleştirir. Bu mimari, Z'yi hesaplayacak olan programın çok uzun olmasına sebep olur. Aritmetik işlemlerin yığının en tepesindeki iki işleneni kullandığını, onları yığından çıkardığını ve daha sonra işlemin sonucunu yığının en tepesine eklediğini öngörelim, kod aşağıdaki gibi oluşur:
Push X 
Push Y 
Mult 
Push W 
Push U 
Mult 
Add 
Store Z
Komutun uzunluğu, işlem kodunun uzunluğundan ve izin verilen işlenen sayısından etkilendiği yukarıda vurgulandı. İşlem kodunun uzunluğu sabit olduğunda, çözme işlemi çok daha kolay olur. Fakat geriye dönük uyumluluk ve esneklik sağlayabilmek için, işlem kodunun uzunluğu değişken olabilir. Değişken uzunluktaki işlem kodlarında, değişken uzunluktaki komutlarda görülen problemlere benzer sorunlar söz konusu olabilir. Birçok tasarımcı işlem kodlarını genişletme konusunda uzlaşmaya varmıştır.