
Bilgisayar Sistemleri #1 — Büyük Resme Bakmak -I-
Herkese merhabalar, bilgisayar sistemleri konulu olacak bir yazı dizisinin ilk bölümü ile birlikte sizleri selamlıyorum. Bu yazının konusu bir bilgisayar sisteminin genel işleyişine detaya girmeden dahil olmaktır yani büyük resme bakmaktır. Belki bu yazı dizisinin sonrasında büyük resmin küçük parçalarını detayları ile birlikte elimden geldiğince sizlerle paylaşabilirim. Eğer ilginizi yeterince çektiyse hadi başlayalım :)
İlk olarak hello adındaki basit ama bir o kadar önemli programın yaşamını inceleyerek başlayacağız. Bu programın programcı tarafından üretildiği andan sistemdeki çalışmasına, çıktı vermesine ve sonlanmasına kadar olan süreçteki anahtar konseptleri, terminolojiyi ve bileşenleri inceleyeceğiz.
Bilgi Bitler ve Bağlamlardan Oluşur.
Bizim hello adındaki programımız geliştiricinin bir text editör veya IDE(Integrated Development Environment) yardımıyla yazdığı source code(kaynak kodu) ile hayatına başlar. Source code dosyaları ASCII tabanlı metin dosyalarıdır ve bit kümelerinden oluşurlar. Her bir bitin değeri 0 veya 1 şeklindedir. Organize edilmiş 8-bit byte olarak adlandırılır. Her bir byte metin içerisindeki bir karakteri temsil eder.
hello.c programı byte kümelerinden oluşan bir dosya içerisinde saklanır. Her byte bir tamsayı değer tutar ve ASCII’de bu tamsayılar karakterleri temsil eder. ASCII karakterleri içeren dosyalar text files(metin dosyaları) olarak bilinirken diğer dosyalar binary files olarak adlandırılır.
hello.c dosyası temel bir fikri işaret eder. Sistemdeki bütün bilgiler- disk dosyaları, bellekteki programlar, bellekte tutulan kullanıcı bilgileri- bit kümelerinden oluşur. Farklı verileri ayıran tek şey onları görüntülediğimiz bağlamdır(context). Programcılar olarak sayıların makine temsillerini anlamamız gerekir çünkü onlar tamsayı ve reel sayı ile aynı değildir. Beklenmedik şekilde davranabilen sonlu yaklaşımlardır.
ASCII Örneği:
# i n c l u d e //#include
35 105 110 99 108 117 100 101 //ve her bir karakterin ASCII değerihello.c
#include <stdio.h>
int main() {
printf("hello, world\n");
return 0;
}Programlar, Programlar Tarafından Farklı Formlara Dönüştürülür.
hello programı hayatına başladığında high-level bir C programıdır çünkü bir insan tarafından kolayca okunabilir ve anlaşılabilir bir formdadır. Ancak hello sistemde yürütüldüğünde, C ifadeleri diğer programlar tarafından low-level makine dili talimatlarına dönüştürülür. Bu talimatlar executable object program formu altında paketlenir ve binary disk dosyası olarak saklanır.
Bir Unix sistemde source file object file’a compiler driver ile dönüştürülür:
gcc -o hello hello.c

Dönüşüm işlemi dört fazdan oluşur bu fazlar preprocessor, compiler, assembler ve linker’dır. Bu fazların tamamının bulunduğu bu sistem compiler system olarak bilinir.
Preprocessing Phase(cpp):
Preprocessor orjinal C programını, kaynak kod içerisinde bulunan ve # işareti ile başlayan yönergelere(örneğin #include) göre değiştirir ve soneki .i olan bir text file oluşturur.
Compilation Phase(cc1):
Derleyici hello.i text dosyasını assembly-language program olan hello.s text dosyasına dönüştürür. Assembly-language program içerisindeki her bir ifade bir tane low-level machine-language talimatını tanımlar. Assembly Language kullanışlıdır çünkü farklı derleyici ve farklı seviyedeki diller için genel bir çıktı dilidir. Örneğin C ve Fortran derleyicileri aynı assembly language çıktısı üretir.
Assembly Phase(as):
Assembler hello.s dosyasını makine dili talimatlarına dönüştürür. Sonuçları hello.o obje dosyası içerisinde tutar. hello.o bir binary dosyasıdır ve byteları karakter yerine makine dili talimatları kodlar.
Linking Phase(ld):
Bu aşamada hello programı her C derleyicisinin sağladığı standart C library’nin parçası olan printf’i çağırır ve bu bizim hello.o ile birleşir. Bu birleştirme işlemini linker gerçekleştirir. Sonuçta çıkan hello dosyası executable object file ya da kısaca executable olarak adlandırılır. Bu dosya belleğe yüklenmeye ve sistem tarafından gerçeklenmeye hazırdır.
Derleme Sistemi Nasıl Çalışır?
hello.c gibi basit programlar için derleme sistemine doğru ve etkili makine kodu üretmesi konusunda güvenebiliriz ancak yine de bir programcının compilation systems’in nasıl çalıştığını anlaması aşağıdaki sebepler dolayısı ile gereklidir.
Program Performansını Optimize Etmeye Yardımcı Olur:
Modern derleyiciler kaliteli kod üretmek için özel araçlara sahiptir. Bir programcı olarak verimli kod yazmak için derleyicinin iç işleyişini bilmek zorunda değiliz. Ancak programlarımızda kaliteli kod yazmak amacıyla, alacağımız kararların doğru olması için machine-level kodları ve derleyicinin programlarımızı nasıl dönüştürdüğünü temel olarak anlamalıyız.
Bağlama Zamanı Hatalarını Anlamayı Sağlar:
En şaşırtıcı program hatalarının genellikle linker operasyonlarından kaynaklandığını görmekteyiz. Özellikle de büyük yazılım sistemlerinin geliştirilmesi sırasında. Bu sebeple compilation systems’in anlaşılması bu hataların da anlaşılmasına katkı sağlar.
Güvenlik Açıklarından Kaçınmaya Yardımcı Olur:
Uzun yıllar boyunca ağ ve internet sunucularındaki en büyük güvenlik açıkları buffer overflow (arabellek taşması) sorunlarıydı. Bu güvenlik açıkları olur çünkü çok az sayıda programcı güvenilmeyen kaynaklardan kabul edilen verilerin niceliği ve formlarını dikkatli bir şekilde kısıtlama gereksinimini anlamıştır. Güvenli programlamadaki ilk adım, veri ve kontrol bilgisinin stack’deki depolanma sonuçlarının anlaşılmasıdır.
Eveet! ‘Büyük Resme Bakmak’ isimli kısa yazı dizisinin ilk bölümünü burada sonlandırıyorum. Sonraki yazılarda bilgisayar sisteminin donanım organizasyonundan, işletim sisteminden ve onun donanımı nasıl yönettiğinden vs. bahsedeceğiz.
Gelecek yazıda görüşmek üzere :)
Bu metinde başta “Computer Systems: A Programmer Perspective 2nd Edition, Bryant O’Hallaron” olmak üzere pek çok farklı kaynaktan faydalanılmıştır.
Bu ve bundan sonra gelecek yazılar için https://gokhanyahyatorba.wordpress.com/ adresini takip edebilirsiniz.
