Makine Dili Nasıl Yapılanır: CPU Talimatlarının Sınıflandırılması

Kerem Aydın·8 Temmuz 2026·⏱5 dk

İşlemci komutları (talimatlar), merkezi işlem biriminin doğrudan gerçekleştirdiği temel işlemlerdir. Metin düzenleyicilerden karmaşık oyunlara kadar tüm programlar, nihayetinde bu basit eylemlerin bir dizisine indirgenir. Temel talimat türleri beş gruba ayrılır: aritmetik-mantıksal (hesaplamalar), veri taşıma (kopyalama), akış kontrolü (dallanma ve döngüler), bellek işlemleri (yükleme/kaydetme) ve sistem (çalışma modu yönetimi). Bu yapıyı anlamak, kodu optimize etmeye ve bilgisayarın çalışma prensibini daha derinlemesine kavramaya yardımcı olur.

Talimat Seti Mimarisi (ISA)

Talimat seti (Instruction Set Architecture, ISA), yazılım ile donanım arasındaki arayüzdür. Belirli bir işlemcinin anladığı "sözlük" budur. ISA tasarımında iki temel yaklaşım vardır:

  1. CISC (Complex Instruction Set Computer) — karmaşık komut seti. x86 mimarisi (Intel, AMD) için karakteristiktir. Komutlar tek bir saat döngüsünde birden fazla işlem gerçekleştirebilir (örneğin, bellekten okuma, toplama ve sonucu yazma).
  2. RISC (Reduced Instruction Set Computer) — azaltılmış komut seti. ARM (akıllı telefonlar, Apple Silicon) ve RISC-V için karakteristiktir. Komutlar son derece basittir ve tek bir saat döngüsünde yürütülür; bu da pipelining'i kolaylaştırır ve enerji verimliliğini artırır.

Önemli: Günümüzde CISC ve RISC arasındaki sınır bulanıklaşmıştır. x86 işlemciler, karmaşık komutları dahili olarak basit mikro işlemlere (uOps) dönüştürerek düşük seviyede RISC makineleri gibi çalışır.

Temel İşlemci Talimat Türleri

Mimari ne olursa olsun, tüm talimatlar işlevsel gruplara ayrılabilir. Her grup, bilgi işlemenin belirli bir aşamasından sorumludur.

1. Aritmetik-Mantıksal Talimatlar (ALU İşlemleri)

Bu komutlar hesaplamaları gerçekleştirir. İşlemci register'larında bulunan verileri işlerler.

  • Aritmetik: ADD (toplama), SUB (çıkarma), MUL (çarpma), DIV (bölme), INC (artırma), DEC (azaltma).
  • Mantıksal: AND, OR, XOR (özel VEYA), NOT (değilleme). Bit düzeyinde veri işleme, maskeler ve flag'ler için kullanılırlar.
  • Kaydırma: SHL/SAL (sola kaydırma), SHR (mantıksal sağa kaydırma), SAR (aritmetik sağa kaydırma). İkinin katlarıyla çarpma veya bölme işlemlerini etkili bir şekilde yerine getirirler.

Bu işlemlerin sonuçları genellikle flag register'ını (x86'da EFLAGS/RFLAGS) etkiler; "sıfır sonucu", "taşma" veya "negatif değer" bitlerini ayarlar.

2. Veri Taşıma Talimatları (Data Movement)

En sık kullanılan komut grubudur. Verileri değiştirmez, register'lar, bellek ve giriş-çıkış portları arasında taşır.

  • MOV / LDR / STR: Kaynaktan alıcıya değer kopyalama.
  • PUSH / POP: Yığın (stack) ile çalışma. PUSH veriyi yığının tepesine yerleştirir, POP veriyi çıkarır. Fonksiyon çağrıları ve bağlamın korunması için kritik öneme sahiptir.
  • LEA (Load Effective Address): Belleğe gerçekten erişmeden bellek adresini hesaplama. Genellikle gösterici aritmetiği için hızlı bir yöntem olarak kullanılır.

Yeni başlayanların sık yaptığı hata: Yüksek seviye dillerdeki atama işlemini veri taşıma ile karıştırmak. Assembly dilinde MOV A, B, B'deki değeri A'ya kopyalar ancak onları kalıcı olarak bağlamaz. A'nın sonraki değişiklikleri B'yi etkilemez.

3. Akış Kontrol Talimatları (Control Flow)

Bu komutlar olmadan program kesinlikle yukarıdan aşağıya doğru lineer olarak çalışırdı. Koşullar, döngüler oluşturmaya ve fonksiyonları çağırmaya olanak tanır.

  • Koşulsuz dallanmalar: JMP (Jump) veya B (Branch). İşlemci sadece belirtilen bellek adresine geçer.
  • Koşullu dallanmalar: JE (Eşitse Atla), JNE (Eşit Değilse Atla), JG (Büyükse Atla). Yalnızca durum register'ındaki belirli flag'ler önceki bir aritmetik işlem tarafından (örneğin CMP) ayarlanmışsa yürütülür.
  • Prosedür çağrıları: CALL ve RET. CALL, dönüş adresini yığına kaydeder ve alt programa geçer. RET, adresi yığından geri yükler ve kontrolü iade eder.

4. Bellek Erişim Talimatları (Memory Access)

ARM gibi RISC mimarilerinde, ana belleğe erişim yalnızca özel yükleme ve kaydetme komutları aracılığıyla mümkündür. x86'da birçok aritmetik komut doğrudan bellekle çalışabilir, ancak bu yürütmeyi yavaşlatır.

  • LOAD (Yükleme): Bellek hücresinden register'a veri okuma.
  • STORE (Kaydetme): Register'dan bellek hücresine veri yazma.

Bu işlemlerin hızı, işlemci önbelleğine (L1, L2, L3) büyük ölçüde bağlıdır. Önbellekte bulma (Cache Hit) nanosaniyeler içinde gerçekleşirken, önbellek isabeti olmaması (Cache Miss) yüzlerce saat döngüsüne mal olabilir.

5. Sistem ve Ayrıcalıklı Talimatlar

Normal uygulamalar bu komutları doğrudan kullanamaz. Bunlar yalnızca işletim sistemi çekirdeği veya sürücüler tarafından kullanılabilir.

  • Kesmeler: INT, SYSCALL. Korumalı işlemleri (dosya okuma, bellek tahsisi) gerçekleştirmek için kontrolün işletim sistemine devredilmesi.
  • Mod yönetimi: Kullanıcı modu (Ring 3) ile çekirdek modu (Ring 0) arasında geçiş yapma.
  • TLB ve önbellek ile çalışma: Adres çeviri tablolarının geçersiz kılınması, önbelleğin temizlenmesi.

x86-64 ve ARMv8 Talimatlarının Karşılaştırılması

Yaklaşımlar arasındaki farkı görmek için, aynı mantığın farklı mimarilerde nasıl uygulandığını karşılaştıralım.

Eylemx86-64 (CISC)ARMv8-A (RISC)Açıklama
ToplamaADD RAX, RBXADD X0, X0, X1ARM'de üç register'ı açıkça belirtmek gerekir (sonuç, operand1, operand2).
Bellekten yüklemeMOV RAX, [addr]LDR X0, [X1]x86, aritmetik içinde belleğe erişime izin verirken, ARM ayrı bir yükleme gerektirir.
KarşılaştırmaCMP RAX, RBXCMP X0, X1Her iki mimari de sonucu kaydetmeden flag'leri ayarlamak için çıkarma kullanır.
Koşullu dallanmaJE labelB.EQ labelSöz dizimi farklıdır, ancak flag kontrol mantığı aynıdır.

Talimatlar Performansı Nasıl Etkiler?

Modern işlemciler talimatları tek tek yürütmez. Pipeline (işlem hattı) ve sıra dışı yürütme (out-of-order execution) kullanırlar.

  1. Getirme (Fetch): İşlemci birkaç talimatı önceden okur.
  2. Çözümleme (Decode): Karmaşık x86 komutları mikro işlemlere ayrılır.
  3. Yürütme (Execute): Mikro işlemler boşta olan yürütme birimlerine (portlara) dağıtılır.
  4. Yazma (Write-back): Sonuçlar register'lara kaydedilir.

Optimizasyon: Kodun hızlı çalışması için veri bağımlılıklarından (data hazards) kaçının. Örneğin, bir sonraki komut öncekinin sonucunu kullanıyorsa, işlemcinin beklemesi gerekir. Tüm yürütme bloklarını yüklemek için bağımsız talimatları gruplayın.

Assembly Öğrenirken Sık Yapılan Hatalar

  • Bellek hizalamasını görmezden gelmek: Verilere kelime boyutunun katı olmayan adreslerden erişmek (örneğin, tek bir adresten 4 bayt okumak) bir istisnaya neden olabilir veya performansı ciddi şekilde düşürebilir.
  • Endianness'i anlamamak: Bellekteki bayt sırası (x86/ARM'de Little Endian, ağ protokollerinde Big Endian'a karşı) çok baytlı sayıların yorumlanmasında hatalara yol açar.
  • Yığın taşması: Sonsuz özyineleme veya çok büyük yerel diziler yığın belleğini tüketebilir ve bu da programın çökmesine (Stack Overflow) neden olur.

SSS

Komut ile mikro işlem arasındaki fark nedir? Komut, program kodunda yazılan şeydir (ISA talimatı). Mikro işlem (µop), işlemcinin yürütmek için komutu parçaladığı dahili temsildir. Tek bir karmaşık x86 komutu 3–4 mikro işleme dönüşebilir.

Neden programları doğrudan assembly ile yazamıyoruz? Bu mümkündür ancak büyük projeler için pratik değildir. Assembly, register'ların ve belleğin manuel yönetimini gerektirir, mimariler arasında taşınabilir değildir (Intel kodu ARM'de çalışmaz) ve bakımı son derece zahmetlidir. Modern dillerin (C++, Rust) derleyicileri genellikle insanlardan daha optimal kod üretir.

SIMD talimatları nedir? SIMD (Single Instruction, Multiple Data), tek bir işlemi aynı anda birden fazla veri elemanına uygulayan komutlardır. Örneğin, AVX-512 talimatı tek bir saat döngüsünde 16 çift kayan nokta sayısını toplayabilir. Bu, grafikler, bilimsel hesaplamalar ve video işleme için kritik öneme sahiptir.