Bölüm 1: Programlama Dilleri

Mikroişlemciler
Yazılım ve dil seviyeleriMakine diliÖrnek komut biçimi Çevirici (assembly) dillerFarklı platformlarda “Merhaba” Derlenen dillerYorumlanan dillerAynı program 14 dilde + 8086
Sercan KÜLCÜ · Giresun Üniversitesi · Elektrik-Elektronik Mühendisliği

Giriş

Öğrenme Çıktıları

Dil seviyeleri

Makine dili, çevirici dil ve yüksek seviyeli diller arasındaki farkı açıklamak.

Makine kodu

Bir komut biçimine göre ikili komutları kodlamak ve çözmek.

Assembly

Etiket, komut, işlenen, yönerge kavramlarını tanımak; sistem çağrısı yapan kısa programları okumak.

Platform bağımlılığı

Aynı programın x86, 68000, ARM, PowerPC ve farklı işletim sistemlerinde neden farklı yazıldığını açıklamak.

Derleme ve yorumlama

Derleyici, bağlayıcı, yorumlayıcı ve JIT kavramlarını karşılaştırmak.

Diller arası okuma

Aynı algoritmayı farklı dillerde ve 8086 assembly ile izlemek.

Yazılım

Yazılım

  • Bilgisayar donanımını düzgün, koordineli ve istenen şekilde çalıştırır.
  • İşletim sistemi
    • bilgisayarın temel yazılımıdır,
    • donanımı yönetir, diğer yazılımların çalışmasını denetler.
  • Programlama dilleri
    • yazılım geliştirmek için icat edilmiştir,
    • farklı alanlara yönelik çok sayıda dil vardır.
  • Programlama dillerinin evrimi, bilgisayar teknolojisindeki önemli gelişmeleri yansıtır.
Kullanıcı Uygulamalartarayıcı, derleyici, oyun İşletim sistemisistem çağrıları, sürücüler DonanımCPU, bellek, G/Ç

Yazılım

Programlama Dilleri: Seviyeler

DerlenenC, Rust, Go YorumlananPython, Ruby Yüksek seviyeli diller Çevirici dil (assembly)MOV AL, 5 Makine dili1011 0000 0000 0101 soyutlama artar donanım (işlemci)
  1. Makine dilleri: işlemcinin doğrudan çalıştırdığı 0 ve 1'ler.
  2. Çevirici diller: makine komutlarının sembolik (anımsatıcı) yazımı.
  3. Yüksek seviyeli diller
    • derlenen: önce makine diline çevrilir, sonra çalışır;
    • yorumlanan: çalışma anında satır satır işlenir.
Seviye yükseldikçe taşınabilirlik ve okunabilirlik artar, donanım üzerindeki doğrudan denetim azalır.

Yazılım · Adım adım

Aynı İşlem Üç Seviyede: x = a + b

Yüksek seviye (C)x = a + b;Değişkenlerin nerede durduğu, hangi yazmacın kullanılacağı derleyiciye bırakılır.
Çevirici dil (8086)
MOV AX, [a]     ; a'yı AX yazmacına yükle
ADD AX, [b]     ; AX = AX + b
MOV [x], AX     ; sonucu x'e yaz
Her satır tek bir makine komutuna karşılık gelir.
Makine dili (a = 0200h, b = 0202h, x = 0204h)
A1 00 02        ; MOV AX, [0200h]
03 06 02 02     ; ADD AX, [0202h]
A3 04 02        ; MOV [0204h], AX
Adresler bellekte düşük bayt önce (little-endian) saklanır: 0200h → 00 02.

Makine Dili

Makine Dilleri

  • 0 ve 1'lerden oluşan en alt seviyeli dildir; işlemci yalnızca bunu anlar.
  • Tamamen işlemciye ve donanıma bağımlıdır: 8086 için yazılan makine kodu ARM'da çalışmaz.
  • İlk genel amaçlı elektronik bilgisayarlardan ENIAC (1945), kablolar ve anahtarlarla doğrudan donanım üzerinde programlanıyordu.
  • Günümüzde
    • her işlemci ailesinin kendine özgü bir makine dili (komut kümesi) vardır,
    • okuması ve yazması pratik olmadığı için doğrudan kullanılmaz.
  • Çevirici diller makine diline bağımlılığı azaltır ve daha insan dostu bir programlama sağlar.
8086'da B0 05 baytları “AL'ye 5 yükle” demektir. Aynı iş ARM'da 32 bitlik tamamen farklı bir sözcükle kodlanır.

Makine Dili

Örnek Bir Makine Dili Tasarımı

o o o o h h k k bit 7bit 0 işlem kodu (4 bit) hedef (2 bit) kaynak (2 bit)
İşlem koduAnlamı
0000HALT: programı durdur
0001ADD: toplama
0010SUB: çıkarma
0011AND: mantıksal VE
0100OR: mantıksal VEYA
  • Komutlar 8 bitliktir.
  • 4 yazmaç: R0 = 00, R1 = 01, R2 = 10, R3 = 11.
  • Anlam: hedef ← hedef işlem kaynak.
  • 4 bitlik işlem kodu en çok 24 = 16 işlem tanımlayabilir; burada 5'i kullanılıyor.
Örnek: 0001 10 11 → ADD R2, R3 → R2 ← R2 + R3

Makine Dili

Örnek Program: Alanları Ayırmak

Makine koduİşlemHedefKaynakAnlamı
0001 0001ADDR0R1R0 ← R0 + R1
0011 1011ANDR2R3R2 ← R2 AND R3
0100 0110ORR1R2R1 ← R1 OR R2
0000 0000HALT——programı durdur
Kaynak sunumda yorumlar sonucu ikinci yazmaca yazıyordu (“R0 ve R1'i topla, sonucu R1'e kaydet”). Tanımlanan biçimde ilk 2 bitlik alan hedef olduğu için sonuç ilk yazmaca (R0, R2, R1) yazılır; yorumlar buna göre düzeltildi.

Onaltılık karşılıkları: 11h, 3Bh, 46h, 00h.

Makine Dili · Kodu adım adım çalıştır

Kod İzleme: Örnek Makine Programı

Başlangıç değerleri (örnek). PC = 0: ilk komut getirilecek.

ADD R0, R1: 5 + 3 = 8 → R0. Kaynak (R1) değişmez.

AND R2, R3: 1100 AND 1010 = 1000 → R2 = 8. Yalnızca iki tarafta da 1 olan bit kalır.

OR R1, R2: 0011 OR 1000 = 1011 → R1 = 11.

HALT: işlemci durur. Sonuç: R0 = 8, R1 = 11, R2 = 8, R3 = 10.

0001 0001   ; ADD R0, R1 → R0 ← R0 + R1
0011 1011   ; AND R2, R3 → R2 ← R2 AND R3
0100 0110   ; OR  R1, R2 → R1 ← R1 OR R2
0000 0000   ; HALT

Makine Dili · Etkileşimli

Kodlayıcı ve Çözücü

⇄

Üstteki seçimleri değiştir (kodlama) ya da sağdaki kutuya 8 bit yaz (çözme). 0101–1111 işlem kodları bu tasarımda tanımsızdır.

Makine Dili

Makine Dili: Artılar ve Eksiler

Artılar

  • Çeviri gerekmez; işlemci doğrudan çalıştırır.
  • Donanım üzerinde tam denetim.
  • En küçük ve (doğru yazılırsa) en hızlı kod.

Eksiler

  • Okuması, yazması ve hata ayıklaması çok zor.
  • Adresler elle hesaplanır; araya bir komut eklemek tüm atlama adreslerini bozar.
  • Taşınabilir değil: her işlemci için baştan yazılır.
  • Tek bir bit hatası programı tamamen değiştirir.
Bu sorunları çözmek için önce çevirici diller (1950'ler), ardından FORTRAN (1957) gibi yüksek seviyeli diller geliştirildi.

Çevirici Diller

Çevirici (Assembly) Diller

  • Her makine komutu, akılda kalır bir anımsatıcıyla (mnemonic) yazılır: 10110000 00000101 yerine MOV AL, 5.
  • Farklı işlemci mimarilerine ve komut kümelerine göre tasarlanır: Intel x86, Motorola 68000, ARM, PIC, AVR için ayrı çevirici diller vardır.
  • Mikrodenetleyicilere özel çevirici diller gömülü sistemlerde ve elektronik uygulamalarda sıkça kullanılır.
  • Bir işlemci ailesi içinde uyumu sağlar ve donanım özelliklerinden en iyi şekilde yararlanmayı amaçlar.
  • Kaynak kodu makine diline çeviren programa çevirici (assembler) denir.
Nerede kullanılır?önyükleyici, aygıt sürücüleri, kesme yordamları, işletim sistemi çekirdeği
Neden öğrenilir?işlemcinin gerçekte nasıl çalıştığını anlamak, hata ayıklama, tersine mühendislik
Performansderleyicinin üretemediği özel komutlar (SIMD, kripto) ve kritik döngüler

Çevirici Diller

Kaynak Koddan Çalışan Programa

prog.asmkaynak çevirici prog.objnesne kodu bağlayıcı prog.exeçalıştırılabilir + kütüphaneler (.lib/.obj) MASM, NASM, TASM, GASLINK, ld yükleyici → bellek

Çeviricinin liste (listing) çıktısı, her satırın adresini ve makine kodunu yan yana gösterir:

Adres   Makine kodu   Kaynak
0100    B4 09         mov ah, 09h
0102    BA 0C 01      mov dx, offset mesaj
0105    CD 21         int 21h
0107    B8 00 4C      mov ax, 4C00h
010A    CD 21         int 21h
010C    4D 65 72 ...  mesaj db 'Merhaba!$'

emu8086 bu adımları tek tuşla yapar ve COM/EXE dosyasını doğrudan üretir.

Çevirici Diller

Bir Assembly Satırının Yapısı

dongu: add ax, cx ; toplama ekle etiket anımsatıcı işlenenler yorum (çevirici yok sayar)
ÖğeGöreviÖrnek
Etiketbir adrese isim verir; atlama ve veri hedefidongu:, mesaj
Anımsatıcımakine komutunun adıMOV, ADD, JMP, INT
İşlenenleryazmaç, sabit ya da bellek; 8086'da önce hedef, sonra kaynakAX, 5 · [BX], AL
Yönerge (directive)makine kodu üretmez, çeviriciye talimat verirORG 100h, DB, SECTION, EQU
Yorum; ile başlar (ARM GNU'da @, PPC'de #); açıklama

Çevirici Diller

Çeviriciler ve Sözdizimleri

ÇeviriciSözdizimi · kullanım
MASMIntel · Microsoft, Windows
TASMIntel · Borland, DOS
NASMIntel · açık kaynak, çok platform
GAS (as)AT&T · GNU/Linux, gcc
emu8086Intel (MASM benzeri) · 8086 benzetimcisi, bu ders

Aynı komut, iki yazım

; Intel:  hedef, kaynak
mov eax, 5
add eax, [ebx+4]

# AT&T:  kaynak, hedef
movl $5, %eax
addl 4(%ebx), %eax

AT&T'de yazmaçlar %, sabitler $ ile yazılır; boyut komut sonekinde (l = 32 bit) belirtilir.

Çevirici Diller · Kodu adım adım çalıştır

x86 Assembly: Linux (32 bit, NASM)

Veri bölümü: dizge ve sonuna satır sonu (10). len, $ - hello ile 16 olarak hesaplanır.

Program _start'tan başlar. EAX = 4: sys_write sistem çağrısı numarası.

EBX = 1: yazılacak dosya tanıtıcısı stdout (ekran).

ECX = dizgenin adresi (içeriği değil).

EDX = 16 (10h): yazılacak bayt sayısı.

int 0x80: çekirdek çağrılır, metin yazılır. Dönüşte EAX = yazılan bayt sayısı (16).

EAX = 1: sys_exit.

xor ebx, ebx: bir sayı kendisiyle XOR'lanınca 0 olur → çıkış kodu 0 (başarı). mov ebx, 0'dan kısadır.

Çekirdek süreci 0 çıkış koduyla sonlandırır; bu çağrı geri dönmez.

section .data
hello  db 'Merhaba, Linux!', 10
len    equ $ - hello     ; = 16 bayt
section .text
global _start
_start:
  mov eax, 4     ; sys_write
  mov ebx, 1     ; stdout
  mov ecx, hello ; dizgenin adresi
  mov edx, len   ; bayt sayısı
  int 0x80       ; çekirdeği çağır
  mov eax, 1     ; sys_exit
  xor ebx, ebx   ; çıkış kodu 0
  int 0x80

Kaynakta sabit 15 bayt yazılıyordu; “Merhaba, Dünya!” metninde ü harfi UTF-8'de 2 bayt olduğundan (16 bayt) “!” kesiliyordu. equ $ - hello uzunluğu çeviriciye hesaplatır.

Çevirici Diller

Sistem Çağrısı Nasıl Çalışır?

Kullanıcı programıEAX=4 EBX=1ECX=adres EDX=16 Çekirdek (kernel)EAX'e göre hizmettablosundan seçer Sürücü · donanımterminal / ekranint 0x80EAX = sonuçkullanıcı kipiçekirdek kipi (ayrıcalıklı)
OrtamÇağrıHizmet numarasıParametreler
Linux 32 bitint 0x80EAX (4 = write, 1 = exit)EBX, ECX, EDX
Linux 64 bitsyscallRAX (1 = write, 60 = exit)RDI, RSI, RDX
MS-DOSint 21hAH (09h = yaz, 4Ch = çık)DX, AL …
BIOSint 10hAH (0Eh = karakter yaz)AL, BH …

Çevirici Diller · Kodu adım adım çalıştır

x86 Assembly: DOS (emu8086, COM)

org 100h: COM programı kesimin 100h adresine yüklenir (önceki 256 bayt PSP). CS = DS = ES = SS.

AH = 09h: DOS'un “$ ile biten dizgeyi yaz” hizmeti.

lea dx, mesaj: DS:DX dizgenin adresini gösterir. Kod 13 bayt (0100h–010Ch) olduğundan mesaj 010Dh'de.

int 21h: DOS, '$' görene kadar karakterleri ekrana yazar ('$' yazılmaz).

AX = 4C00h: AH = 4Ch “programı sonlandır”, AL = 00h çıkış kodu.

Program biter, denetim DOS'a döner. Veri kodun arkasında olduğu için işlemci hiçbir zaman veriyi komut sanıp çalıştırmaz.

org 100h          ; COM programı
mov ah, 09h       ; DOS 09h: dizge yaz
lea dx, mesaj     ; DS:DX = adres
int 21h           ; DOS hizmetini çağır
mov ax, 4C00h     ; DOS 4Ch: sonlandır
int 21h
mesaj db 'Merhaba, DOS!$'

Kaynaktaki sürümde dizge 0 ile bitiyordu ve veri kodun önündeydi; 09h hizmeti '$' sonlandırıcı bekler ve öndeki veri komut gibi çalıştırılırdı. AL'nin de sıfırlanması için mov ax, 4C00h kullanıldı.

Çevirici Diller

x86 Assembly: Windows (Win32 API, NASM)

extern MessageBoxA    ; user32.dll
extern ExitProcess    ; kernel32.dll

section .data
mesaj db 'Merhaba, Windows!', 0

section .text
global _start
_start:
    push 0          ; uType = MB_OK
    push mesaj      ; lpCaption (başlık)
    push mesaj      ; lpText (metin)
    push 0          ; hWnd = NULL
    call MessageBoxA
    push 0          ; uExitCode = 0
    call ExitProcess
Farklar
  • Sistem çağrısı yok: işletim sistemi hizmetleri DLL fonksiyonları olarak çağrılır.
  • Parametreler yığına sağdan sola itilir: C'deki MessageBoxA(hWnd, lpText, lpCaption, uType).
  • stdcall: yığını çağrılan fonksiyon temizler.
  • Dizgeler 0 ile biter (C dizgesi).
  • Bağlarken süslenmiş ad gerekebilir: _MessageBoxA@16 (16 = parametre baytı).

Çevirici Diller · Kodu adım adım çalıştır

Kod İzleme: Parametreler Yığına

yüksek adres ↑0012FF80h0012FF7Ch0012FF78h0012FF74h0012FF70h0012FF6Chdüşük adres ↓ (yığın bu yöne büyür)ESP→

Başlangıç: ESP = 0012FF80h (örnek değer). Yığın düşük adreslere doğru büyür.

yüksek adres ↑0012FF80h0012FF7Ch0uType = MB_OK0012FF78h0012FF74h0012FF70h0012FF6Chdüşük adres ↓ (yığın bu yöne büyür)ESP→

push 0: ESP 4 azalır, son parametre (uType) önce itilir.

yüksek adres ↑0012FF80h0012FF7Ch0uType = MB_OK0012FF78h&mesajlpCaption0012FF74h0012FF70h0012FF6Chdüşük adres ↓ (yığın bu yöne büyür)ESP→

push mesaj: başlık dizgesinin adresi itilir.

yüksek adres ↑0012FF80h0012FF7Ch0uType = MB_OK0012FF78h&mesajlpCaption0012FF74h&mesajlpText0012FF70h0012FF6Chdüşük adres ↓ (yığın bu yöne büyür)ESP→

push mesaj: metin dizgesinin adresi.

yüksek adres ↑0012FF80h0012FF7Ch0uType = MB_OK0012FF78h&mesajlpCaption0012FF74h&mesajlpText0012FF70h0hWnd = NULL0012FF6Chdüşük adres ↓ (yığın bu yöne büyür)ESP→

push 0: ilk parametre (hWnd) en son itilir → yığının tepesinde. Parametreler sağdan sola itilir.

yüksek adres ↑0012FF80h0012FF7Ch0uType = MB_OK0012FF78h&mesajlpCaption0012FF74h&mesajlpText0012FF70h0hWnd = NULL0012FF6Chdönüş adr.call'dan sonraki komutdüşük adres ↓ (yığın bu yöne büyür)ESP→

call MessageBoxA: dönüş adresi itilir ve fonksiyona atlanır; ekranda ileti kutusu açılır.

yüksek adres ↑0012FF80h0012FF7Ch0012FF78h0012FF74h0012FF70h0012FF6Chdüşük adres ↓ (yığın bu yöne büyür)ESP→

Kullanıcı Tamam'a basınca fonksiyon ret 16 ile döner: stdcall'da yığını çağrılan temizler, ESP yeniden 0012FF80h. EAX = 1 (IDOK).

yüksek adres ↑0012FF80h0012FF7Ch0uExitCode = 00012FF78h0012FF74h0012FF70h0012FF6Chdüşük adres ↓ (yığın bu yöne büyür)ESP→

push 0 + call ExitProcess: süreç 0 çıkış koduyla sonlanır; bu çağrı geri dönmez.

extern MessageBoxA
extern ExitProcess
section .data
mesaj db 'Merhaba...', 0
section .text
global _start
_start:
  push 0       ; uType
  push mesaj   ; lpCaption
  push mesaj   ; lpText
  push 0       ; hWnd
  call MessageBoxA
  push 0       ; uExitCode
  call ExitProcess

Çevirici Diller

Motorola 68000 Assembly: Amiga

    move.l  4.w,a6         ; a6 = ExecBase
    lea     dosname(pc),a1 ; kütüphane adı
    moveq   #0,d0          ; herhangi bir sürüm
    jsr     -552(a6)       ; OpenLibrary()
    tst.l   d0
    beq.s   cik            ; açılamadı → çık
    move.l  d0,a6          ; a6 = DOSBase
    jsr     -60(a6)        ; Output() → d0
    move.l  d0,d1          ; dosya tanıtıcısı
    move.l  #mesaj,d2      ; dizgenin adresi
    moveq   #16,d3         ; bayt sayısı
    jsr     -48(a6)        ; Write(d1,d2,d3)
    move.l  a6,a1
    move.l  4.w,a6
    jsr     -414(a6)       ; CloseLibrary()
cik moveq   #0,d0          ; dönüş kodu 0
    rts
dosname dc.b 'dos.library',0
mesaj   dc.b 'Merhaba, Amiga!',10
Farklar
  • 8 veri (d0–d7) ve 8 adres (a0–a7) yazmacı; kaynak, hedef sırası.
  • Boyut soneki: .b, .w, .l; sabitler # ile.
  • Hizmetler kütüphane tabanından negatif uzaklıkla (-48(a6)) çağrılır.
  • Kütüphane açılır, kullanılır, kapatılır.

Kaynaktaki sürüm A6'ya 14 ve 20 sabitlerini yükleyip oraya atlıyordu (geçersiz adres) ve ayrıcalıklı STOP komutuyla bitiyordu; AmigaOS'un exec/dos kütüphane çağrılarıyla düzeltildi.

Çevirici Diller

ARM Assembly: Linux (32 bit, GNU as)

    .data
mesaj:  .ascii "Merhaba, ARM!\n"
uzun = . - mesaj       @ 14 bayt

    .text
    .global _start
_start:
    mov  r7, #4        @ sys_write
    mov  r0, #1        @ stdout
    ldr  r1, =mesaj    @ dizgenin adresi
    mov  r2, #uzun     @ bayt sayısı
    svc  #0            @ çekirdeği çağır
    mov  r7, #1        @ sys_exit
    mov  r0, #0        @ çıkış kodu
    svc  #0
Farklar
  • RISC: 16 yazmaç (r0–r15), sabit 32 bitlik komutlar.
  • Hizmet numarası r7'de, parametreler r0–r2'de.
  • Çekirdeğe geçiş: svc #0 (eski adı swi).
  • Bellekten yalnızca ldr/str ile okunur/yazılır.

Düzeltmeler: GNU as'ta db değil .ascii kullanılır; “Merhaba, ARM!” 13 karakterdir, kaynaktaki 15 bayt dizgenin dışını yazıyordu.

Çevirici Diller

PowerPC (PPC) Assembly: Linux (32 bit)

    .data
mesaj:  .ascii "Merhaba, PowerPC!\n"
uzun = . - mesaj        # 18 bayt

    .text
    .globl _start
_start:
    li   0, 4           # r0 = sys_write
    li   3, 1           # r3 = stdout
    lis  4, mesaj@ha    # r4 = adres (üst)
    addi 4, 4, mesaj@l  #    + alt yarı
    li   5, uzun        # r5 = bayt sayısı
    sc                  # çekirdeği çağır
    li   0, 1           # r0 = sys_exit
    li   3, 0           # r3 = çıkış kodu
    sc
Farklar
  • RISC: 32 genel yazmaç; GNU as'ta yazmaçlar düz sayıyla yazılır (3 = r3).
  • Hizmet numarası r0'da, parametreler r3, r4, r5'te; geçiş sc.
  • 32 bitlik adres, 16 bitlik iki parçada yüklenir (@ha, @l).

Kaynaktaki sürümde hizmet numarası r4'e, adres olarak yığın işaretçisi (r1) r5'e konuyordu; Linux PPC çağrı kuralına göre düzeltildi.

Çevirici Diller

Aynı “Merhaba”, Altı Ortam

OrtamİşlemciOS'a geçişHizmet no.ParametrelerDizge sonu
Linuxx86 (32)int 0x80EAXEBX, ECX, EDXuzunluk verilir
DOS8086int 21hAHDX (adres)'$'
Windowsx86 (32)call DLLfonksiyon adıyığın0
AmigaOS68000jsr -48(a6)kütüphane uzaklığıd1, d2, d3uzunluk verilir
LinuxARMsvc #0r7r0, r1, r2uzunluk verilir
LinuxPowerPCscr0r3, r4, r5uzunluk verilir
Assembly kodu hem işlemciye (komut kümesi, yazmaçlar) hem de işletim sistemine (çağrı yolu, numaralar) bağlıdır. Yüksek seviyeli dillerin en büyük kazancı bu bağımlılığı derleyiciye/yorumlayıcıya devretmektir.

Yüksek Seviyeli Diller

Yüksek Seviyeli Diller

Derlenen diller
  • Kaynak kod önceden makine diline çevrilir.
  • Hataların çoğu derleme sırasında yakalanır.
  • Performans avantajı sağlar.
  • Aşamalar: derleme (compiler) ve bağlama (linker).
  • Çıktı belirli bir işlemci + işletim sistemine özgüdür.
Yorumlanan diller
  • Kaynak kod çalışma anında yorumlayıcı tarafından işlenir.
  • Hızlı geliştirme ve deneme imkânı sağlar.
  • Kaynak kod platformdan bağımsızdır: yorumlayıcı olan her yerde çalışır.
  • Hatalar ancak ilgili satır çalışınca ortaya çıkabilir.
  • Genelde daha yavaştır.
Hibrit yaklaşım: Java ve C# önce ara koda (bytecode/IL) derlenir; sanal makine bu kodu çalışırken makine diline çevirir (JIT, just-in-time). Python ve JavaScript motorları da içeride bytecode/JIT kullanır.

Yüksek Seviyeli Diller · Adım adım

Derleme Süreci (C, gcc)

1 · Önişlemci#include ve #define açılır → tekcift.i (gcc -E)
2 · DerleyiciC kodu sözdizimi ve tip denetiminden geçer, assembly'ye çevrilir → tekcift.s (gcc -S)
3 · ÇeviriciAssembly, makine koduna çevrilir → nesne dosyası tekcift.o (gcc -c)
4 · BağlayıcıNesne dosyası, printf/scanf gibi kütüphane kodlarıyla birleştirilir → çalıştırılabilir tekcift / tekcift.exe
5 · Yükleyiciİşletim sistemi programı belleğe yükler ve main'e atlar.

Tek komutla: gcc tekcift.c -o tekcift. Ara assembly'yi görmek için gcc -S -masm=intel tekcift.c.

Yüksek Seviyeli Diller · Derlenen

Derlenen Diller

  • Kaynak kod çalışmadan önce derleyici tarafından bütünüyle incelenir.
  • Derlenmiş kod doğrudan işlemcide çalıştığı için daha hızlıdır.
  • Tip ve sözdizimi hataları derleme aşamasında tespit edilir.
C ve C++sistem programlaması, işletim sistemleri, gömülü yazılım ve yüksek performanslı uygulamalar
Rustgüvenli ve performanslı sistem programlaması (bellek güvenliği derleyicide denetlenir)
Fortranbilimsel ve sayısal hesaplamalar; ilk yüksek seviyeli dil (1957)
Gosunucu ve ağ yazılımı; hızlı derleme, eşzamanlılık
Adahavacılık, savunma, demiryolu gibi güvenlik-kritik sistemler
Java, C# (hibrit)ara koda derlenir, sanal makinede JIT ile çalışır

Yüksek Seviyeli Diller · Kodu adım adım çalıştır

Görev: 1'den n'ye Tek/Çift — C

Bütün örnek programlar aynı işi yapar: bir sayı okur, 1'den o sayıya kadar her sayının tek mi çift mi olduğunu yazar.

Kullanıcı 3 girer. scanf'e değişkenin adresi (&number) verilir.

Döngü başlar: i = 1, koşul 1 ≤ 3 doğru.

1 % 2 = 1 ≠ 0 → else dalı: “tek”.

i++ → 2; 2 ≤ 3 doğru.

2 % 2 = 0 → “çift”.

i = 3; 3 ≤ 3 doğru.

3 % 2 = 1 → “tek”.

i = 4; 4 ≤ 3 yanlış → döngü biter.

return 0: işletim sistemine “başarılı” çıkış kodu.

#include <stdio.h>

int main() {
    int number;
    printf("Bir sayi girin: ");
    scanf("%d", &number);
    for (int i = 1; i <= number; i++) {
        if (i % 2 == 0) {
            printf("%d sayisi bir cift sayidir.\n", i);
        } else {
            printf("%d sayisi bir tek sayidir.\n", i);
        }
    }
    return 0;
}

Yüksek Seviyeli Diller · Derlenen

C++

#include <iostream>

int main() {
    int number;
    std::cout << "Bir sayi girin: ";
    std::cin >> number;
    for (int i = 1; i <= number; i++) {
        if (i % 2 == 0) {
            std::cout << i << " sayisi bir cift sayidir."
                      << std::endl;
        } else {
            std::cout << i << " sayisi bir tek sayidir."
                      << std::endl;
        }
    }
    return 0;
}
C++ (1985, Bjarne Stroustrup)
  • C'nin üst kümesi; sınıflar, şablonlar, istisnalar.
  • G/Ç için akışlar: std::cout << yazar, std::cin >> okur.
  • Derleme: g++ tekcift.cpp -o tekcift
  • std::endl satır sonu ekler ve tamponu boşaltır; çok satırda '\n' daha hızlıdır.

Yüksek Seviyeli Diller · Derlenen (ara koda)

C#

using System;

class Program {
  static void Main() {
    Console.Write("Bir sayi girin: ");
    int number = int.Parse(Console.ReadLine());
    for (int i = 1; i <= number; i++) {
      if (i % 2 == 0) {
        Console.WriteLine($"{i} sayisi bir cift sayidir.");
      } else {
        Console.WriteLine($"{i} sayisi bir tek sayidir.");
      }
    }
  }
}
C# (2000, Microsoft)
  • .NET platformu; IL ara diline derlenir, CLR çalışırken JIT ile makine koduna çevirir.
  • $"{i} …": dizge içine değer yerleştirme (interpolation).
  • Çalıştırma: dotnet run
  • int.Parse sayı olmayan girdide istisna fırlatır; int.TryParse daha güvenlidir.

Yüksek Seviyeli Diller · Derlenen (bytecode)

Java

import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    System.out.print("Bir sayi girin: ");
    int number = scanner.nextInt();
    for (int i = 1; i <= number; i++) {
      if (i % 2 == 0) {
        System.out.println(i + " sayisi bir cift sayidir.");
      } else {
        System.out.println(i + " sayisi bir tek sayidir.");
      }
    }
  }
}
Java (1995, Sun Microsystems)
  • javac → platformdan bağımsız bytecode (.class) → JVM'de JIT.
  • “Bir kez yaz, her yerde çalıştır.”
  • Çalıştırma: javac Main.java ve java Main
  • Her şey bir sınıf içinde; dosya adı = public sınıf adı.

Yüksek Seviyeli Diller · Derlenen

Go

package main

import "fmt"

func main() {
    var number int
    fmt.Print("Bir sayi girin: ")
    fmt.Scan(&number)
    for i := 1; i <= number; i++ {
        if i%2 == 0 {
            fmt.Printf("%d sayisi bir cift sayidir.\n", i)
        } else {
            fmt.Printf("%d sayisi bir tek sayidir.\n", i)
        }
    }
}
Go (2009, Google)
  • Doğrudan makine koduna derlenir; tek, bağımsız çalıştırılabilir dosya.
  • Çöp toplayıcı ve hafif iş parçacıkları (goroutine).
  • Çalıştırma: go run tekcift.go
  • Koşul ve döngülerde parantez yok; := tipi çıkarır.

Yüksek Seviyeli Diller · Derlenen

Rust

use std::io;

fn main() {
    let mut input = String::new();
    println!("Bir sayi girin:");
    io::stdin().read_line(&mut input)
        .expect("okuma hatasi");
    let number: i32 = input.trim().parse()
        .expect("cevirme hatasi");
    for i in 1..=number {
        if i % 2 == 0 {
            println!("{} sayisi bir cift sayidir.", i);
        } else {
            println!("{} sayisi bir tek sayidir.", i);
        }
    }
}
Rust (2015, Mozilla)
  • Çöp toplayıcı olmadan bellek güvenliği: sahiplik (ownership) kuralları derleyicide denetlenir.
  • Değişkenler varsayılan olarak değiştirilemez; mut gerekir.
  • 1..=number: üst sınır dahil aralık.
  • Çalıştırma: rustc tekcift.rs ya da cargo run

Yüksek Seviyeli Diller · Derlenen

Fortran

program Main
    implicit none
    integer :: number, i
    write(*,*) 'Bir sayi girin:'
    read(*,*) number
    do i = 1, number
        if (mod(i, 2) == 0) then
            write(*,*) i, ' sayisi bir cift sayidir.'
        else
            write(*,*) i, ' sayisi bir tek sayidir.'
        end if
    end do
end program Main
Fortran (1957, IBM · John Backus)
  • İlk yaygın yüksek seviyeli dil: FORmula TRANslation.
  • Bilimsel hesaplamada hâlâ yaygın (hava tahmini, fizik).
  • implicit none: tüm değişkenler açıkça tanımlanmalı.
  • Çalıştırma: gfortran tekcift.f90 -o tekcift
  • write(*,*) serbest biçim yazar; sayıların önünde boşluk görülebilir.

Yüksek Seviyeli Diller · Derlenen

Ada

with Ada.Text_IO;         use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure Main is
   Number : Integer;
begin
   Put ("Bir sayi girin: ");
   Get (Number);
   for I in 1 .. Number loop
      Put (I, Width => 0);
      if I mod 2 = 0 then
         Put_Line (" sayisi bir cift sayidir.");
      else
         Put_Line (" sayisi bir tek sayidir.");
      end if;
   end loop;
end Main;
Ada (1983, ABD Savunma Bakanlığı)
  • Güçlü tip denetimi; havacılık ve savunma yazılımı.
  • Çalıştırma: gnatmake main.adb
  • Düzeltme: tamsayı Get/Put için Ada.Integer_Text_IO gerekir; kaynaktaki Put'lar satır sonu eklemediği için tüm çıktı tek satırda kalıyordu → Put_Line.

Yüksek Seviyeli Diller · Yorumlanan

Yorumlanan Diller

  • Kaynak kod çalışma anında yorumlanır; ayrı bir derleme adımı yoktur.
  • Hızlı geliştirme ve deneme (etkileşimli kabuk, REPL).
Pythongenel amaçlı, yüksek seviyeli; veri bilimi, yapay zekâ
JavaScriptweb geliştirme; tarayıcıda ve Node.js'te çalışır
Rubykullanım kolaylığı ve esneklik; Ruby on Rails
tekcift.py yorumlayıcı (CPython) sıradaki ifadeyi oku çözümle (bytecode'a çevir) çalıştır

Yüksek Seviyeli Diller · Yorumlanan

Python

# Kullanıcıdan girdi alma
number = int(input("Bir sayi girin: "))

# 1'den number'a kadar sayıları kontrol et
for i in range(1, number + 1):
    if i % 2 == 0:
        print(f"{i} sayisi bir cift sayidir.")
    else:
        print(f"{i} sayisi bir tek sayidir.")
Python (1991, Guido van Rossum)
  • Bloklar süslü parantezle değil girintiyle belirlenir.
  • range(1, number + 1): üst sınır dahil değildir, bu yüzden +1.
  • input metin döndürür; int(...) sayıya çevirir.
  • Çalıştırma: python tekcift.py
  • Dinamik tipli: değişkenin tipi çalışırken belirlenir.
C sürümünde 15 satır gereken iş 6 satırda: yüksek seviyeli dillerin ifade gücü. Bedeli: CPython aynı döngüyü C'den onlarca kat yavaş çalıştırır.

Yüksek Seviyeli Diller · Yorumlanan (JIT)

JavaScript

// Kullanıcıdan girdi alma
let number = Number(prompt("Bir sayi girin:"));

// 1'den number'a kadar sayıları kontrol et
for (let i = 1; i <= number; i++) {
    if (i % 2 === 0) {
        console.log(i + " sayisi bir cift sayidir.");
    } else {
        console.log(i + " sayisi bir tek sayidir.");
    }
}
JavaScript (1995, Brendan Eich)
  • Tarayıcıların dili; Node.js ile sunucuda da çalışır.
  • Modern motorlar (V8) kodu JIT ile makine koduna çevirir.
  • prompt metin döndürür; Number(...) ile çevirmek güvenlidir (kaynakta çevrilmeden karşılaştırılıyordu).
  • ===: tip dönüştürmeden eşitlik.

Yüksek Seviyeli Diller · Yorumlanan

Ruby

# Kullanıcıdan girdi alma
print "Bir sayi girin: "
number = gets.chomp.to_i

# 1'den number'a kadar sayıları kontrol et
for i in 1..number do
  if i % 2 == 0
    puts "#{i} sayisi bir cift sayidir."
  else
    puts "#{i} sayisi bir tek sayidir."
  end
end
Ruby (1995, Yukihiro Matsumoto)
  • Her şey bir nesnedir: gets.chomp.to_i art arda metot çağrısıdır.
  • chomp satır sonunu atar, to_i tamsayıya çevirir.
  • 1..number: üst sınır dahil aralık.
  • "#{i}": dizge içine değer yerleştirme.
  • Çalıştırma: ruby tekcift.rb

Yüksek Seviyeli Diller · Yorumlanan

PHP

<?php
// Kullanıcıdan girdi alma
echo "Bir sayi girin: ";
$number = (int) trim(fgets(STDIN));

// 1'den number'a kadar sayıları kontrol et
for ($i = 1; $i <= $number; $i++) {
    if ($i % 2 == 0) {
        echo $i . " sayisi bir cift sayidir.\n";
    } else {
        echo $i . " sayisi bir tek sayidir.\n";
    }
}
?>
PHP (1995, Rasmus Lerdorf)
  • Sunucu tarafı web dili; HTML içine gömülebilir.
  • Değişkenler $ ile başlar; . dizge birleştirir.
  • fgets(STDIN) komut satırından bir satır okur; trim satır sonunu atar.
  • Çalıştırma: php tekcift.php

Yüksek Seviyeli Diller · Yorumlanan

Perl

use strict;
use warnings;

# Kullanıcıdan girdi alma
print "Bir sayi girin: ";
my $number = <STDIN>;
chomp $number;

# 1'den number'a kadar sayıları kontrol et
for my $i (1..$number) {
    if ($i % 2 == 0) {
        print "$i sayisi bir cift sayidir.\n";
    } else {
        print "$i sayisi bir tek sayidir.\n";
    }
}
Perl (1987, Larry Wall)
  • Metin işleme ve sistem yönetimi; güçlü düzenli ifadeler.
  • <STDIN> bir satır okur, chomp satır sonunu atar.
  • Çift tırnaklı dizgede $i doğrudan değerle değiştirilir.
  • use strict; use warnings; yaygın hataları yakalar.
  • Çalıştırma: perl tekcift.pl

Yüksek Seviyeli Diller · Yorumlanan

MATLAB

% Kullanıcıdan girdi alma
number = input('Bir sayi girin: ');

% 1'den number'a kadar sayıları kontrol et
for i = 1:number
    if mod(i, 2) == 0
        fprintf('%d sayisi bir cift sayidir.\n', i);
    else
        fprintf('%d sayisi bir tek sayidir.\n', i);
    end
end
MATLAB (1984, MathWorks)
  • Matris tabanlı sayısal hesaplama; mühendislikte, özellikle sinyal işleme ve denetimde yaygın.
  • 1:number: 1, 2, …, number vektörü.
  • Satır sonundaki ; sonucun ekrana basılmasını engeller.
  • Ücretsiz uyumlu alternatif: GNU Octave.

Yüksek Seviyeli Diller

Aynı Program, On Dört Dil

DilModelDöngü başlığıKalanYazdırma
Cderlenenfor (int i = 1; i <= n; i++)i % 2printf
C++derlenenfor (int i = 1; i <= n; i++)i % 2std::cout <<
C#IL + JITfor (int i = 1; i <= n; i++)i % 2Console.WriteLine
Javabytecode + JITfor (int i = 1; i <= n; i++)i % 2System.out.println
Goderlenenfor i := 1; i <= n; i++i%2fmt.Printf
Rustderlenenfor i in 1..=ni % 2println!
Fortranderlenendo i = 1, nmod(i, 2)write(*,*)
Adaderlenenfor I in 1 .. N loopI mod 2Put_Line
Pythonyorumlananfor i in range(1, n + 1):i % 2print
JavaScriptyorumlanan/JITfor (let i = 1; i <= n; i++)i % 2console.log
Rubyyorumlananfor i in 1..n doi % 2puts
PHPyorumlananfor ($i = 1; $i <= $n; $i++)$i % 2echo
Perlyorumlananfor my $i (1..$n)$i % 2print
MATLAByorumlanan/JITfor i = 1:nmod(i, 2)fprintf

Yüksek Seviyeli Diller

Derlenen, Yorumlanan, Hibrit

ÖlçütDerlenenYorumlananHibrit (bytecode + JIT)
Çeviri zamanıçalışmadan önce, bir kezher çalıştırmadaönce ara koda, sonra çalışırken
Hızen yükseken düşükyüksek (ısındıktan sonra)
Dağıtılanmakine kodukaynak kodara kod (.class, .dll)
Taşınabilirlikher platform için yeniden derleyorumlayıcı olan her yersanal makine olan her yer
Hata yakalamaçoğu derlemedeçoğu çalışırkentip hataları derlemede
ÖrnekC, C++, Go, Rust, Fortran, AdaPython, Ruby, PHP, Perl, MATLABJava, C#, JavaScript (V8)
“Derlenen/yorumlanan” dilin değil gerçeklemenin özelliğidir: C için yorumlayıcı, Python için derleyici (Cython, PyPy JIT) de vardır.

Köprü · Kodu adım adım çalıştır

Aynı Görev 8086 Assembly ile (n = 3)

CX sayaç (i) olarak kullanılır: i = 1. n = 3 sabit (okuma işlemi sonraki bölümlerde).

cmp cx, 3: 1 − 3 hesaplanır (sonuç saklanmaz) → ZF=0, CF=1 (ödünç). ja yalnız CF=0 ve ZF=0 iken atlar → atlamaz.

DL = 1 + 30h = 31h: rakam 1'in ASCII kodu. ADD bayrakları günceller: CF=0.

DOS 02h hizmeti DL'deki karakteri yazar.

test cl, 1: 1 AND 1 = 1 ≠ 0 → ZF=0 → jnz tek atlar. (i % 2 yerine en düşük bit.)

DX = tek_m dizgesinin adresi; 09h hizmeti '$'a kadar yazar. 0Dh, 0Ah satır başı + satır sonudur.

inc cx → 2 (INC, CF'yi değiştirmez); döngü başına dönülür.

2 − 3: CF=1 → devam.

DL = 32h ('2') yazılır.

2 AND 1 = 0 → ZF=1 → jnz atlamaz: sayı çift.

DX = cift_m; jmp yaz ile ortak yazdırma koduna gidilir.

“çift” iletisi yazılır.

CX = 3.

3 − 3 = 0 → ZF=1, CF=0. ZF=1 olduğu için ja atlamaz (3 ≤ 3).

'3' yazılır; 3 AND 1 = 1 → ZF=0 → tek.

“tek” iletisi yazılır.

CX = 4.

4 − 3 = 1 → ZF=0, CF=0 → ja bitti atlar (4 > 3).

ret: COM programı DOS'a döner. C'deki for + if, burada karşılaştırma + koşullu atlama çiftleriyle kuruldu.

org 100h
       mov  cx, 1       ; i = 1
dongu: cmp  cx, 3       ; i ile n karşılaştır
       ja   bitti       ; i > n ise bitir
       mov  dl, cl
       add  dl, '0'     ; rakam → ASCII
       mov  ah, 02h
       int  21h         ; DL'yi yaz
       test cl, 1       ; en düşük bit
       jnz  tek         ; 1 ise tek
       lea  dx, cift_m
       jmp  yaz
tek:   lea  dx, tek_m
yaz:   mov  ah, 09h
       int  21h         ; dizgeyi yaz
       inc  cx          ; i++
       jmp  dongu
bitti: ret
tek_m  db ' sayisi bir tek sayidir.',0Dh,0Ah,'$'
cift_m db ' sayisi bir cift sayidir.',0Dh,0Ah,'$'

Özet

Özet

  • Yazılım donanımı yönetir; işletim sistemi temel yazılımdır, programlama dilleri yazılım geliştirmek için kullanılır.
  • Makine dili işlemcinin tek anladığı dildir: işlem kodu ve işlenen alanlarından oluşan ikili komutlar; donanıma tamamen bağımlıdır.
  • Çevirici dil makine komutlarını anımsatıcılarla yazar; çevirici ve bağlayıcı ile çalıştırılabilir dosyaya dönüşür. Kod hem işlemciye hem işletim sistemine bağlıdır (int 0x80, int 21h, DLL çağrısı, svc, sc).
  • Derlenen diller (C, C++, Go, Rust, Fortran, Ada) önceden makine koduna çevrilir: hızlı, ama platforma özgü.
  • Yorumlanan diller (Python, JavaScript, Ruby, PHP, Perl, MATLAB) çalışırken işlenir: hızlı geliştirme, taşınabilir kaynak, daha yavaş çalışma. Java/C# ara kod + JIT ile ikisinin arasındadır.
  • Yüksek seviyedeki for/if, assembly'de karşılaştırma + koşullu atlama olarak gerçeklenir.

Özet

Alıştırmalar

  1. Örnek makine dilinde SUB R3, R0 ve OR R0, R2 komutlarını ikili ve onaltılık olarak kodlayın.
  2. 0010 0111 komutunu çözün. R1 = 9, R3 = 4 ise sonuç nedir?
  3. Bu tasarımda kaç farklı işlem kodu tanımlanabilir? Yazmaç sayısını 8'e çıkarmak için komut biçimi nasıl değişmeli?
  4. DOS programında dizge sonundaki '$' unutulursa ne olur?
  5. Linux örneğinde len elle 15 yazılsaydı ekrana ne çıkardı?
  6. Windows örneğinde parametreler neden ters sırada itilir? call'dan hemen sonra ESP kaçtır?
  7. Java neden “derlenen” ya da “yorumlanan” diye tek kelimeyle sınıflanamaz?
İpuçları / cevaplar
  1. 0010 1100 = 2Ch; 0100 0010 = 42h.
  2. SUB R1, R3 → R1 ← 9 − 4 = 5.
  3. 24 = 16. 8 yazmaç için 3'er bit gerekir: 4 + 3 + 3 = 10 bit (ya da işlem kodu 2 bite iner).
  4. DOS ilk '$' karakterine rastlayana kadar bellekteki rastgele baytları ekrana basar.
  5. “Merhaba, Linux!” yazılır ama satır sonu basılmaz (16. bayt).
  6. C çağrı kuralında ilk parametre yığının tepesinde olmalıdır; 4 push + dönüş adresi → ESP = 0012FF80h − 20 = 0012FF6Ch.
  7. Önce bytecode'a derlenir, sonra JVM'de yorumlanır/JIT ile derlenir: hibrittir.

Özet

Kaynaklar

  • Tanenbaum ve Bos, Modern Operating Systems, 3. baskı, Pearson.
  • Brey, The Intel Microprocessors, 8. baskı, Pearson.
  • Irvine, Assembly Language for x86 Processors, 7. baskı, Pearson.
  • NASM belgeleri (nasm.us) ve GNU Binutils as kılavuzu.
  • Ralf Brown's Interrupt List (DOS INT 21h hizmetleri); Microsoft Win32 API belgeleri (MessageBoxA, ExitProcess).
  • emu8086 belgeleri ve 8086 komut kümesi başvurusu.

Son

Bölüm 1: Programlama Dilleri
Sonraki bölüm: Bölüm 2: 8086 Pinler
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.