İşlem kodunun buyruk içindeki yeri. Üstte RISC-V'in R ve I biçimleri, altta x86'nın değişken uzunluklu kodlaması. Kırmızı alanlar işlemi, gri alanlar işlenenleri belirtir.

İşlem kodu (İngilizce: opcode ya da operation code), bir makine dili buyruğunun, işlemcinin gerçekleştireceği işlemi belirten kısmıdır. İşlem kodunun özellikleri ve biçimi, söz konusu işlemcinin buyruk kümesi mimarisinde tanımlanır. Bir buyruk, normalde işlem kodundan ve üzerinde işlem yapılacak bir ya da daha fazla işlenenden oluşur; ancak bazı buyruklar örtük (implicit) işlenene sahip olabilir ya da hiç işleneni bulunmayabilir.

İşlem kodu ve anımsatıcı

Çevirici dilde işlem, ikili kodu yerine okunabilir bir anımsatıcı (İngilizce: mnemonic) ile yazılır. Anımsatıcı işlem kodunun kendisi değildir; çeviricinin, işlenenlerin türüne ve boyutuna bakarak seçtiği kodlamaya karşılık gelen bir addır. Tek bir anımsatıcı çoğu zaman birden çok işlem koduna eşlenir: aynı ad, işlenenler yazmaç ya da anlık değer olduğunda, boyut değiştiğinde ya da adresleme yöntemi farklılaştığında ayrı kodlamalar üretir.

Eşleme ters yönde de bire bir değildir. Bir kodlamanın birden çok kabul edilen adı bulunabilir; ayrıca birçok çevirici, donanımda karşılığı olmayan sözde buyruklar tanır ve bunları var olan bir işlem koduna sabit işlenenlerle çevirir. RISC-V'de bir yazmacı bir başkasına kopyalayan buyruk, sıfır eklemeli toplama olarak kodlanır; işlem yapmayan buyruk da aynı işlem kodunun bir başka özel durumudur. Bu yüzden ikili koddan çevirici dile geri dönen ayrıştırma, kaynak metni birebir geri vermez.

İşlem kodunun yapısı

Bir buyruk, buyruk kümesi mimarisine göre sabit veya değişken uzunlukta olabilir. Her iki durumda da işlem kodu buyruğun belirli bir alanını kaplar:

  • Sabit uzunluklu buyruklar: Tüm buyruklar aynı bit genişliğine sahiptir; işlem kodu alanı da sabit uzunluktadır. RISC mimarilerinde yaygındır. Örneğin RISC-V mimarisinde tüm temel buyruklar 32 bittir ve işlem kodu alanı 7 bittir (bit 0–6).
  • Değişken uzunluklu buyruklar: Farklı buyruklar farklı uzunluklarda olabilir; bu durum işlem kodunun uzunluğunu önceden belirsiz kılar. x86 mimarisi bu yapıya tipik bir örnektir; işlem kodları 1–3 bayt arasında değişir ve önek (prefix) baytlarıyla daha da genişletilebilir.

Kodlama uzunluğu ve yoğunluk

İşlem koduna ayrılan bit sayısı, buyruk kodlamasının merkezindeki ödünleşimi belirler. Alan genişledikçe tanımlanabilecek işlem sayısı artar, ama aynı buyruğun içinde işlenenlere kalan yer azalır. Bu yüzden işlem kodu uzunluğu bağımsız bir seçim değildir; yazmaç sayısı, anlık değerlerin genişliği ve desteklenen adresleme yöntemleriyle birlikte kararlaştırılır.

Sabit uzunluklu kodlamada her buyruğun nerede başladığı adresten okunur. İşlemci art arda gelen buyrukları birbirinden bağımsız olarak çözebilir, bu da aynı çevrimde birden çok buyruğun çözülmesini kolaylaştırır. Bedeli boşa giden kodlama alanıdır; en yalın buyruk da en karmaşığı kadar yer kaplar.

Değişken uzunluklu kodlamada bu ilişki tersine döner. Sık kullanılan buyruklar kısa kodlanabildiği için program bellekte daha az yer tutar ve buyruk önbelleğinden daha çok iş çıkar. Buna karşılık bir buyruğun nerede bittiği ancak çözülerek anlaşılır; sonraki buyruğun başlangıcı bir öncekinin uzunluğuna bağlıdır ve çözme işlemi doğası gereği sıralı hâle gelir. Geniş başlatımlı işlemcilerde bu darboğaz, buyruk uzunluklarının önbelleğe alınırken önceden çıkarılıp saklanmasıyla aşılmıştır.

Kod yoğunluğu

Bir kodlamanın aynı işi kaç baytta anlattığına kod yoğunluğu denir. Gömülü sistemlerde program belleği maliyetin doğrudan bir parçası olduğundan bu ölçü belirleyicidir, ama etkisi orada bitmez; daha yoğun kodlanmış bir program buyruk önbelleğine daha çok sığar ve bellekten daha az veri çekilir. Ölçümler, sabit uzunluklu klasik RISC kodlamalarının bu ölçütte değişken uzunluklu kodlamaların gerisinde kaldığını göstermiştir.

Bu yüzden sabit uzunluklu mimariler kısa buyruk kodlamalarını sonradan bir seçenek olarak eklemiştir. Sık kullanılan işlemler daha dar bir işlem kodu alanı ve kısıtlı bir yazmaç kümesiyle yarı uzunlukta kodlanır; işlemci iki uzunluğu birlikte çözer. RISC-V'in sıkıştırılmış buyruk uzantısı bu yaklaşımın örneğidir ve buyrukların bir bölümünü 32 bit yerine 16 bitle kodlar.

Kodlamanın kendisi bir eniyileme sorunu olarak da ele alınmıştır. Hangi işlemin hangi kod uzunluğunu alacağı, derlenen programlarda ölçülen kullanım sıklığına bakılarak seçildiğinde program boyu belirgin biçimde küçülür; bu, sık geçen simgelere kısa kod veren genel sıkıştırma düşüncesinin buyruk kümesine uygulanmış hâlidir.

İşlem kodu uzayı

Bir işlemcinin destekleyebildiği toplam işlem kodu sayısına işlem kodu uzayı denir. n bitlik bir işlem kodu alanı en fazla 2n farklı buyruk tanımlayabilir. Örneğin 7 bitlik bir işlem kodu alanı teorik olarak 128 farklı buyruk kodlamasına izin verir. Gerçek buyruk kümelerinde bu alanın tamamı kullanılmayabilir; kullanılmayan işlem kodları Geçersiz işlem kodu olarak adlandırılır ve bu kodlar yürütülmeye çalışıldığında işlemci genellikle bir kural dışı durum (exception) üretir. İşlem kodu tablosu, bir mimarinin tüm geçerli işlem kodlarını ve her birine karşılık gelen işlemi listeleyen başvuru tablosudur.

Kaçış koduyla kademelenen kodlama. Her kademede 1111 değeri kaçışa ayrılır; işlem kodu izleyen dört bitte sürer ve işlenen sayısı bir azalır.

Genişleyen işlem kodları

İşlem kodu alanı, tanımlanmak istenen buyruk sayısına yetmediğinde alan büyütülmek yerine bölünebilir. Yöntem, kodlardan birini ya da birkaçını kaçış kodu (İngilizce: escape code) olarak ayırmaktır: bu değer görüldüğünde işlemci, asıl işlemin izleyen bitlerde sürdüğünü anlar. Böylece sabit uzunluklu bir buyruğun içinde değişken uzunluklu bir işlem kodu elde edilir ve kodlama alanı, buyrukların işlenen sayısına göre kademelendirilir.

Kademelenmenin mantığı işlenen sayısıyla kurulur. Üç işlenenli buyruklar işlenen alanlarını doldurduğu için en kısa işlem kodunu alır ve sayıları sınırlı kalır. İşlenen sayısı azaldıkça boşalan alan işlem koduna devredilir; iki işlenenli buyruklar için daha geniş, tek işlenenliler için daha da geniş, hiç işleneni olmayanlar için en geniş kod uzayı açılır. Sonuçta sık kullanılan ve çok işlenenli buyruklar kısa, seyrek kullanılan ve işleneni az olanlar uzun kodlanır.

Aynı düşünce değişken uzunluklu mimarilerde bayt düzeyinde uygulanır. x86 mimarisinde tek baytlık işlem kodu uzayı 1980'lerde dolduğundan bir bayt değeri kaçış olarak ayrılmış ve ikinci bir işlem kodu haritası açılmıştır; sonraki uzantılar için bu haritanın içinden üçüncü düzey haritalar tanımlanmıştır. Vektör uzantılarında ise hangi haritanın kastedildiği, işlem kodundan önce gelen önek baytının içine kodlanarak kaçış dizisinin kapladığı yer geri kazanılmıştır.

Sabit uzunluklu mimarilerde kademelenme, ayrılmış yardımcı alanlarla sağlanır. RISC-V'de 7 bitlik işlem kodu alanı buyruğun biçimini seçer; asıl işlem, o biçimin içindeki funct3 ve funct7 alanlarıyla belirlenir. Bu düzen, tek bir geniş işlem kodu alanı yerine iki kademeli bir çözme sağlar ve yeni buyrukların var olan biçimlerin içine yerleştirilmesine olanak verir.

Örnekler

RISC-V

RISC-V temel tam sayı (RV32I) buyruk kümesinde her buyruk 32 bittir. Bit 6–0 işlem kodunu, geri kalan bitler ise işlenen alanlarını (funct3, funct7, yazmaç numaraları, anlık değerler) taşır. Örneğin ADD buyruğunun işlem kodu alanı 0110011, ADDI buyruğununki ise 0010011 ikilidir.

x86

x86 mimarisinde işlem kodları değişken uzunluktadır. Örneğin MOV buyruğunun çeşitli biçimleri 1 ila 3 bayt işlem koduna sahiptir. İşlenen boyutunu ve adres biçimini belirten önek baytları işlem kodundan önce gelebilir. Bu esneklik güçlü bir kodlama yoğunluğu sağlasa da çözümleme (decode) devrelerini karmaşıklaştırır.

RISC-V işlem kodu alanı

RV32I temel buyruk kümesinde işlem kodu alanı buyruğun en düşük değerlikli yedi bitidir ve doğrudan bir işlemi değil, bir buyruk öbeğini ve o öbeğin biçimini seçer. İşlemin kendisi, seçilen biçimin içindeki funct3 ve funct7 alanlarıyla belirlenir. Aşağıdaki çizelge bu alanın tanımlı değerlerini verir.

RV32I buyruk kümesinde işlem kodu alanının (bit 6-0) değerleri
İşlem kodu Onaltılık Biçim Öbek Örnek buyruklar
0000011 03 I LOAD LB, LH, LW
0001111 0F I MISC-MEM FENCE
0010011 13 I OP-IMM ADDI, SLTI, XORI
0010111 17 U AUIPC AUIPC
0100011 23 S STORE SB, SH, SW
0110011 33 R OP ADD, SUB, AND, OR
0110111 37 U LUI LUI
1100011 63 B BRANCH BEQ, BNE, BLT
1100111 67 I JALR JALR
1101111 6F J JAL JAL
1110011 73 I SYSTEM ECALL, EBREAK

Çizelgede iki düzenlilik göze çarpar. Tanımlı değerlerin hepsi 11 ile biter; bu iki bit işlemin ne olduğunu değil buyruğun 32 bit uzunluğunda olduğunu bildirir ve daha kısa ya da daha uzun kodlamalar için ayrılmıştır. Ayrıca aynı biçim birden çok öbekte kullanılır: I biçimi hem yükleme, hem anlık değerli aritmetik, hem dolaylı atlama, hem de sistem buyrukları için geçerlidir. Böylece yedi bitlik alan, biçim başına ayrı bir çözme yolu açmadan kullanılmış olur.

İşlenenlerin belirtilmesi

İşlem kodunun yanı sıra buyrukta yer alan işlenenler, adresleme yöntemine göre farklı biçimlerde belirtilebilir:

  • Yazmaç numarası (register operand)
  • Anlık değer (immediate), buyruğun içine gömülü sabit sayı
  • Bellek adresi; doğrudan, dolaylı ya da çeşitli adresleme yöntemleriyle
  • Örtük işlenen, işlem kodunun kendisinden anlaşılan, buyrukta ayrıca kodlanmayan işlenen

Dikgenlik

Bir kodlamanın dikgen (İngilizce: orthogonal) sayılması, işlemin seçimi ile işlenenlerin belirtilme biçiminin birbirinden bağımsız olması demektir. Dikgen bir kodlamada her işlem her adresleme yöntemiyle ve her yazmaçla kullanılabilir; işlem kodu ile işlenen alanları ayrı ayrı okunur ve birinin değeri ötekinin seçeneklerini daraltmaz.

Dikgenlik derleyicinin işini kolaylaştırır, çünkü kod üretirken hangi işlemin hangi yazmaçla ya da hangi adresleme yöntemiyle kullanılabildiğinin ayrıca izlenmesi gerekmez. Bedeli kodlama alanıdır; her işlemin her yöntemle birleşebilmesi için buyrukta yeterli genişlikte bağımsız alanlar ayrılmalıdır. PDP-11 ve VAX bu yaklaşımın en çok anılan örnekleridir ve işlenenleri, işlem kodundan bağımsız biçimde okunan tek tip belirteçlerle kodlarlar.

Karşı uçta, kodlama alanından kazanmak için belirli işlemleri belirli yazmaçlara bağlayan kodlamalar bulunur. Bu tasarımlarda çarpma ya da bölme gibi işlemler işlenenlerinden birini buyrukta belirtmez, örtük olarak sabit bir yazmaçtan alır; işlem kodu kısalır, ama derleyicinin yazmaç ataması kısıtlanır ve o yazmaç üzerinde baskı oluşur. 8086 ailesi bu tür kısıtları taşıyan tanınmış bir örnektir.

Yük ve sakla mimarileri araya düşen bir seçim yapar. Yazmaçlar arasında tam dikgenlik korunur, buna karşılık belleğe erişim yalnızca birkaç buyrukla ve az sayıda adresleme yöntemiyle sınırlanır. Böylece kodlama sadeleşir ve işlem kodunun anlamı, işlenenlerin nereden geldiğine bakılmaksızın tek bir işlemi gösterir.

Kullanılmayan, ayrılmış ve belgelenmemiş kodlar

Bir işlem kodu uzayının tamamı hiçbir zaman kullanılmaz. Atanmamış kodlar iki gruba ayrılır: ileride tanımlanmak üzere ayrılmış olanlar ve hiçbir zaman tanımlanmayacağı bildirilenler. Bu ayrımın yazılıp yazılmamış olması, mimarinin sonradan genişletilebilirliğini doğrudan belirler.

Çağdaş mimariler atanmamış her kodlamanın davranışını açıkça tanımlar. Böyle bir kod yürütülmeye çalışıldığında işlemcinin bir kural dışı durum üretmesi zorunlu tutulur; yazılım da bu davranışa güvenerek, işletim sisteminin buyruğu taklit etmesi gibi çözümler kurabilir. RISC-V belirtimi ayrıca kodlama uzayının bir bölümünü uygulayıcıların kendi uzantıları için ayırır, böylece satıcıya özgü buyruklar ileride tanımlanacak standart buyruklarla çakışmaz.

Erken işlemcilerde durum böyle değildi. Çözme mantığı en aza indirildiği için atanmamış kodlar denetlenmeden geçiyor ve devrenin rastlantısal davranışına göre bir iş yapıyordu. Bu belgelenmemiş işlem kodları kimi zaman elle yazılan programlarda kullanıldı; ancak sonraki sürümlerde ya da uyumlu olduğu söylenen başka üreticilerin yongalarında davranış değiştiği için bu programlar çalışmaz duruma geldi. Bugün mimariler, geçerli olmayan bir kodun kasıtlı olarak yürütülebilmesi için ayrıca tanımlanmış bir buyruk da sunar; x86'daki UD2 buyruğu, bu kural dışı durumu bilerek üretmek üzere ayrılmıştır.

Kodlama uzayının sistemli taranması bir araştırma konusudur. Bütün olası kodlamaların üretilip denenmesiyle, üreticinin kılavuzunda geçmeyen buyruklar bulunmuştur; bunların bir bölümü mimarinin belgelenmiş düzeyinin altında, çekirdeğin iç durumuna erişen işlemler yapmaktadır. Bu bulgular, işlem kodu uzayının yalnızca bir tasarım kaynağı değil aynı zamanda bir güvenlik yüzeyi olduğunu göstermiştir.

İşlem kodunun donanımdaki karşılığı

İşlem kodu, buyruğun geri kalanından farklı olarak veri değil denetim taşır. Çözme aşamasında okunan bu alan, veri yolunun geri kalanını yönlendiren denetim işaretlerine dönüştürülür; hangi işlemin gerçekleştirileceğini, işlenenlerin nereden okunacağını ve sonucun nereye yazılacağını belirleyen işaretlerin hepsi buradan türetilir.

Bu dönüşümün iki klasik gerçekleştirimi vardır. Kablolu denetimde işlem kodu, doğrudan bileşimsel bir mantık öbeğinin girişidir ve denetim işaretleri bir çevrimde üretilir. Mikroprogramlanmış denetimde ise işlem kodu bir mikrokod belleğindeki başlangıç adresini seçer; buyruk, oradan okunan mikro buyruk dizisiyle gerçekleştirilir. Düzenli ve sabit uzunluklu kodlamalar kablolu çözmeyi ucuzlattığı için ilkine, karmaşık ve değişken uzunluklu kodlamalar ikincisine yönelmiştir.

Çağdaş yüksek başarımlı gerçekleştirimlerde ikisi bir arada bulunur. Mimarinin tanımladığı işlem kodu, işlemcinin içinde doğrudan yürütülmez; önce iç bir gösterime, daha yalın ve düzenli mikro işlemlere çevrilir. Sık kullanılan buyruklar bu çeviriyi kablolu çözücülerle yapar, seyrek ve karmaşık olanlar mikrokoda yönlendirilir. Böylece işlem kodu, yürütülen biçimle örtüşmeyen ama uyumluluğu taşıyan bir arayüz durumuna gelmiştir.

Kodlama uzayının tükenmesi

İşlem kodu uzayı tüketilebilir bir kaynaktır. Bir mimariye eklenen her yeni yetenek kodlama ister ve bir kez atanan kodlama, geriye uyumluluk gereği geri alınamaz. Uzun ömürlü buyruk kümelerinde bu birikim, kodlamanın tasarımını belirleyen asıl kısıt durumuna gelir.

x86 bu baskının en görünür örneğidir. Tek baytlık uzay dolduktan sonra kaçış baytıyla ikinci bir harita açılmış, sonraki vektör uzantıları için bu harita da yetmeyince kodlanacak bilgi önek baytlarının içine taşınmıştır. Her katman uyumluluğu korumuş, ama çözme mantığını ve doğrulanması gereken durum uzayını büyütmüştür.

Sonradan tasarlanan mimariler bu deneyimi kodlamanın içine yazmıştır. RISC-V belirtimi uzayı baştan bölüştürür: bir bölümü tanımlı buyruklara, bir bölümü ileride tanımlanacak standart uzantılara, ayrı bir bölümü de uygulayıcıların kendi buyruklarına ayrılmıştır. Buyruğun en düşük değerlikli bitleri uzunluğu bildirdiği için, uzunluk çözülmeden önce okunabilir ve daha uzun kodlamalar için yer bırakılmıştır.

Uzayın nasıl bölüştürüleceği, mimarinin ne kadar süre genişletilebileceğini belirler. Kısa ve sık kullanılan kodlamaları erken tüketen bir tasarım, sonraki uzantıları uzun kaçış dizilerine mahkûm eder ve kod yoğunluğunu kuşaklar boyunca aşağı çeker.

Kaynakça

  1. ^ Tanenbaum, Andrew S. (2013). Structured Computer Organization (6 bas.). Pearson. s. 15–18. ISBN 978-0-13-291652-3. 
  2. ^ a b c d e f Patterson, David A.; Hennessy, John L. (2017). Computer Organization and Design: The Hardware/Software Interface (5 bas.). Morgan Kaufmann. s. 78–82. ISBN 978-0-12-407726-3. 
  3. ^ a b c d e f g h Waterman, Andrew; Lee, Yunsup; Patterson, David A. (2014). The RISC-V Instruction Set Manual, Volume I: User-Level ISA, Version 2.0. University of California, Berkeley. doi:10.21236/ada605735. 
  4. ^ a b c d e f Tanenbaum, Andrew S. (2013). Structured Computer Organization (6 bas.). Pearson. s. 20–22. ISBN 978-0-13-291652-3. 
  5. ^ a b c d e f g h i Hennessy, John L.; Patterson, David A. (2019). "Appendix A: Instruction Set Principles". Computer Architecture: A Quantitative Approach (6 bas.). Morgan Kaufmann. ISBN 978-0-12-811905-1. 
  6. ^ Intrater, Gideon; Spillinger, Ilan (1994). "Performance evaluation of a decoded instruction cache for variable instruction length computers". IEEE Transactions on Computers. 43 (10): 1140-1150. doi:10.1109/12.324540. 
  7. ^ a b c d Weaver, Vincent M.; McKee, Sally A. (2009). Code density concerns for new architectures. 2009 IEEE International Conference on Computer Design (ICCD). ss. 459-464. doi:10.1109/iccd.2009.5413117. 
  8. ^ a b Med, Vojtěch; Krall, Andreas (2007). Instruction Set Encoding Optimization for Code Size Reduction. 2007 International Conference on Embedded Computer Systems: Architectures, Modeling and Simulation (SAMOS). ss. 9-17. doi:10.1109/icsamos.2007.4285728. 
  9. ^ a b c d "Intel 64 and IA-32 Architectures Software Developer Manuals" (İngilizce). Intel. Erişim tarihi: 8 Eylül 2026. Arşivlenmesi gereken bağlantıya sahip kaynak şablonu içeren maddeler (link)
  10. ^ Ermolov, Mark; Sklyarov, Dmitry; Goryachy, Maxim (2022). "Undocumented x86 instructions to control the CPU at the microarchitecture level in modern Intel processors". Journal of Computer Virology and Hacking Techniques. 19 (3): 351-365. doi:10.1007/s11416-022-00438-x.