---
title: 'Bağlama ve Yükleme'
source: 'https://academia.sh/tr/kurslar/bilgisayarlar-nasil-calisir/baglama-ve-yukleme'
course: 'Bilgisayarlar Nasıl Çalışır'
language: tr
updated: '2026-08-17T18:08:06+00:00'
license: 'CC BY-SA 4.0'
---

# Bağlama ve Yükleme

Nesne dosyaları, simge çözümleme, statik ve dinamik bağlama ile programın belleğe yüklenmesi.

Önceki ders, kod üretiminin her kaynak dosya için ayrı bir çıktı verdiğini söyledi.
Gerçek bir program ise birçok dosyadan oluşur ve kullandığı kütüphaneler başka
zamanlarda, başka yerlerde derlenmiştir.

Bu dersin sorusu şudur: ayrı ayrı derlenmiş parçalar, tek bir çalışan program hâline
nasıl getirilir?

## Nesne Dosyası

Derleyicinin bir kaynak dosya için ürettiği çıktı doğrudan çalıştırılamaz; buna **nesne
dosyası (object file)** denir. İçinde makine kodu vardır, ancak eksik bilgiler taşır.

Nesne dosyası bölümlere ayrılmıştır. Adlandırma biçimlere göre değişse de içerik
ortaktır:

| Bölüm | İçerik |
|---|---|
| Kod | Yürütülebilir komutlar |
| Salt okunur veri | Sabitler, dizgi sabitleri |
| Başlatılmış veri | Başlangıç değeri verilmiş küresel değişkenler |
| Başlatılmamış veri | Yalnızca boyutu kayıtlı, sıfırlanacak alan |
| Simge tablosu | Tanımlanan ve gereken adlar |
| Yeniden konumlandırma kayıtları | Adres düzeltmesi gereken yerler |

Başlatılmamış veri bölümünün yalnızca boyutu saklanır; içeriği dosyada yer kaplamaz,
çünkü tamamı sıfırdır. Bu, büyük dizilerin tanımlandığı dosyaların neden küçük
kalabildiğini açıklar.

## Simgeler

**Simge (symbol)**, bir ada bağlı bir adrestir: bir fonksiyonun başlangıcı veya bir
küresel değişkenin yeri. Nesne dosyası iki tür simge listeler:

- **Tanımlanan simgeler:** Bu dosyanın sağladığı adlar.
- **Gereken simgeler:** Bu dosyanın kullandığı, ancak başka bir yerde tanımlı adlar.

Derleyici, gereken bir simgeye yapılan çağrıyı üretirken hedef adresi bilmez; yerine
boşluk bırakır ve bu boşluğu yeniden konumlandırma kayıtlarına yazar. "Bu adresi, `topla`
adlı simgenin gerçek adresiyle doldur" notu, kayıtta durur.

## Bağlama

**Bağlayıcı (linker)**, nesne dosyalarını ve kütüphaneleri alıp tek bir çıktı üretir.
Üç iş yapar:

1. **Bölümleri birleştirir.** Tüm dosyaların kod bölümleri art arda, veri bölümleri art
   arda yerleştirilir.
2. **Simgeleri çözer.** Her gereken simge için, onu tanımlayan dosya bulunur.
3. **Adresleri düzeltir.** Yeniden konumlandırma kayıtlarındaki boşluklar, birleştirme
   sonrası kesinleşen adreslerle doldurulur.

Bu aşamanın iki tanınmış hatası vardır ve ikisi de derleyici hatası değildir:

- **Tanımlanmamış simge:** Bir ad kullanılmış ama hiçbir dosyada tanımlanmamış. Yazım
  hatası, eksik kütüphane veya yalnızca bildirimi olup gövdesi yazılmamış bir fonksiyon
  bunu üretir.
- **Yinelenen simge:** Aynı ad birden çok dosyada tanımlanmış. Bağlayıcı hangisini
  seçeceğini bilemez.

Bu hataların derleme değil bağlama aşamasında çıkması, tek bir dosyanın sorunsuz
derlenmesinin programın bütününün doğru olduğu anlamına gelmediğini gösterir.

## Görünürlük ve Ad Karıştırma

Bir dosyadaki her ad, bağlayıcıya görünmek zorunda değildir. Diller, simgeleri iki
görünürlük düzeyine ayırır:

- **Dış görünürlük:** Ad, simge tablosuna yazılır ve başka dosyalardan çözülebilir.
- **İç görünürlük:** Ad yalnızca kendi dosyasında geçerlidir; bağlayıcı onu görmez.

İç görünürlük iki işe yarar: aynı adın farklı dosyalarda çakışmadan kullanılabilmesi ve
bağlayıcının çözmesi gereken simge sayısının azalması. Büyük projelerde bu, bağlama
süresini doğrudan etkiler.

İkinci bir ayrıntı, aynı adın birden çok anlam taşıyabildiği dillerde ortaya çıkar. Aynı
ada sahip ama farklı parametre türleri alan iki fonksiyon, simge tablosunda aynı adla
duramaz. Derleyici bu durumda ada tür bilgisini kodlayarak benzersiz bir simge üretir;
buna **ad karıştırma (name mangling)** denir.

Ad karıştırma düzeni derleyiciye özgüdür ve standartlaşmış değildir. Farklı derleyicilerle
üretilmiş nesne dosyalarının birbirine bağlanamamasının başlıca nedeni budur; diller arası
çağrılarda ise karıştırmayı kapatan bir bildirim kullanılır.

## Statik ve Dinamik Bağlama

Kütüphanelerin programa nasıl katıldığı iki ayrı yaklaşımla çözülür.

**Statik bağlamada** kütüphane kodu, çıktının içine kopyalanır. Sonuç tek ve büyük bir
dosyadır; çalıştığı sistemde başka bir şey aramaz. Kütüphanede sonradan yapılan bir
düzeltme, programın yeniden bağlanmasını gerektirir.

**Dinamik bağlamada** kütüphane ayrı bir dosya olarak kalır; çıktı yalnızca hangi
kütüphaneye ihtiyaç duyduğunu kaydeder. Bağlama işinin bir bölümü, programın
başlatıldığı ana ertelenir.

| Ölçüt | Statik | Dinamik |
|---|---|---|
| Çıktı boyutu | Büyük | Küçük |
| Bellek paylaşımı | Her süreç kendi kopyasını taşır | Aynı kütüphane süreçler arasında paylaşılır |
| Güncelleme | Yeniden bağlama gerekir | Kütüphane dosyası değişince tüm programlar etkilenir |
| Başlatma maliyeti | Yok | Kütüphane bulma ve simge çözme |
| Dağıtım | Kendi kendine yeter | Hedef sistemde uyumlu sürüm bulunmalıdır |

Dinamik bağlamanın güncelleme kolaylığı, aynı zamanda kırılganlık kaynağıdır: beklenenden
farklı bir sürümün bulunması, çalışma anında simge hatası verir. Uyumluluk kurallarının
belgelenmesi ve sürüm işaretlemesi bu nedenle kütüphane geliştirmenin ayrılmaz parçasıdır.

## Yükleme

Program çalıştırıldığında **yükleyici (loader)** devreye girer. Yaptıkları:

1. Çalıştırılabilir dosyanın bölümlerini sürecin adres uzayına yerleştirir.
2. Başlatılmamış veri bölümü için yer ayırır ve sıfırlar.
3. Gerekli dinamik kütüphaneleri bulur, yükler ve kalan simgeleri çözer.
4. Yığıt için alan hazırlar, başlangıç argümanlarını yerleştirir.
5. Program sayacını giriş noktasına yazar; artık akış programındır.

Beşinci adım, önceki konudaki getir–çöz–yürüt döngüsünün başlangıcıdır. Yükleyici,
o döngünün ilk adresini belirleyen bileşendir.

Yükleyici, kodu önceden bilinmeyen bir adrese yerleştirebilir; bu nedenle üretilen
kodun konumdan bağımsız olması istenir. Konumdan bağımsız kod, mutlak
adres yerine göreli adres kullanır ve aynı kütüphanenin farklı süreçlerde farklı
adreslere yüklenmesine izin verir.

## Çalışma Anında Ad Çözme

Dinamik bağlamanın fikri — adın hedefini son ana kadar belirlememek — yorumlanan
dillerde daha da ileri götürülür: ad çözümleme her erişimde yapılır.

```python
import math, sys

# İçe aktarma, adı çalışma anında bir modül nesnesine bağlar.
print(type(math))                      # <class 'module'>
print(math.__name__)                   # math

# Modül nesnesi, adları taşıyan bir sözlüktür.
print("sqrt" in vars(math))            # True

# Ad, çağrı anında çözülür: bağ değiştirilebilir.
gercek_sqrt = math.sqrt
math.sqrt = lambda x: "yerine geçen"
print(math.sqrt(9))                    # yerine geçen
math.sqrt = gercek_sqrt                # eski bağ geri yüklendi
print(math.sqrt(9))                    # 3.0

# Yüklü modüller, yükleyicinin tuttuğu tabloya benzer bir kayıtta durur.
print("math" in sys.modules)           # True
```

Bu esnekliğin bedeli, statik bağlamanın verdiği güvencelerin kaybıdır: yanlış yazılmış
bir ad, ilgili satır çalışana kadar hata üretmez. Bağlama zamanı ile hata görme zamanı
arasındaki ilişki, önceki derste tip denetimi için kurulan ilişkinin aynısıdır.

## Özet

- Derleyicinin çıktısı olan nesne dosyası eksiktir: tanımladığı ve gereksinim duyduğu
  simgeleri listeler, dış adresler için boşluk bırakır.
- Bağlayıcı bölümleri birleştirir, simgeleri çözer ve adresleri düzeltir; tanımlanmamış
  ve yinelenen simge hataları bu aşamada çıkar.
- Statik bağlama kütüphane kodunu çıktıya kopyalar; dinamik bağlama onu ayrı dosyada
  bırakıp çözümü başlatma anına erteler.
- Dinamik bağlama bellek paylaşımı ve kolay güncelleme sağlar, karşılığında sürüm
  uyumluluğu sorumluluğu getirir.
- Yükleyici bölümleri adres uzayına yerleştirir, kütüphaneleri bağlar ve program
  sayacını giriş noktasına yazar.

## Sonraki Adım

Yükleyicinin hazırladığı adres uzayının içi henüz açılmadı: kod nerede durur, küresel
değişkenler nerede, fonksiyon çağrılarının yerel değişkenleri nerede tutulur? Kursun son
dersi bu bölmeleri ve her birinin yaşam süresi kuralını ele alacak.
