Bu bölümde assembler tarafından üretilen COM ve EXE dosyalarının farklarına değineceğim. Her iki program türünün yorumlanış şekillerine, üstünlüklerine ve zayıflıklarına dikkat çekmek istiyorum.

 

Bölüm 4: COM ve EXE Dosya Biçimleri

 

Bugünlerde COM uzantılı dosyaları görmek epey zor olsa da, yine de alt düzey programlama yapan kişiler, bu dosya biçimleri ile sıklıkla çalışmaktadır. 32 bit ortamlarda kullanılan dosya türü EXE ve DOS tarihe karışmak üzere olduğundan, yüksek seviyeli programlama dillerinin derleyicileri(ve bağlayıcıları) artık COM uzantısı seçeneği dahi içermemektedirler.

 

DOS Altında Çalıştırılabilir Dosya Biçimleri

 

DOS'un, bir program dosyası çalıştırılmak üzere açılırken önem verdiği iki şey vardır: Dosyanın adı ve uzantısı. Bu uzantıların öncelikleri sırasıyla COM, EXE ve BAT biçimindedir. Yani 8 karakterlik dosya adı bölümü aynı olan, fakat uzantıları .bat, .exe ve .com olan üç farklı dosya olsun. DOS'ta programı çalıştırmak için dosya adını yazmamızın yeterli olduğunu hepiniz biliyorsunuzdur. Ancak söz konusu dosya adını yazdığınızda çalıştırılacak olan program, uzantısı .com olandır.

 

Her ne kadar bu bölümün başlığında adından söz etmesem de, .bat dosya biçimine de kısaca değinmek isterim. Bu tür dosyaların içerisinde herhangi derlenmiş kod veya bilgi bulunmaz. Bu dosyalar, herhangi bir metin düzenleyici ile içini açıp rahatlıkla okuyabileceğiniz türden dosyalar olup, genellikle yüksek seviyeli dillerdeki makrolar gibi çalışırlar. Komutlar satır satır yorumlanır ve sabit diskinizdeki programların (varsa parametreleri ile birlikte) çağırılmasını, gerekirse programlara giriş çıkış koşullarına varana dek denetlenmesini sağlarlar. Bu komutları klavyeden girmek ile eşdeğer muamele görürler. Windows ortamında kimi yerlerde rastlayabileceğiniz (hatta MPEG dosya biçimlerinde "ID3 Tag" olarak geçen tanımlamalarda görebileceğiniz) %1, %2 gibi simgeler, bu batch dosyalardan gelmektedir. Bu denli basit ve anlaşılır yapıları nedeniyle Windows ortamında bir batch dosyaya sağ tıkladığınızda gelen menüde Düzenle seçeneği dahi bulunur. Bu seçeneğe tıkladığınızda dosya, Not Defteri uygulamasında açılır. Bir batch dosyanın programlama dilleri ile yazılmış kodlar ile en büyük benzerliği, etiketleri ve koşul ifadelerini desteklemesidir. Çeşitli koşullara göre dallanmalar sağlayabileceğiniz durumlar için ":etiket" biçiminde tanımlamalar yapılabilir ve "goto" deyimi ile bu etiketlerden çalışmaya devam edilir. İşte bu noktada .bat uzantılı dosyaların da derlendiği gerçeğine ulaşılır. DOS, önce dosyanın tamamını belleğe alarak etiketleri ve şartlı ifadeleri çözümler. Böylece programın herhangi bir yerinde goto veya if deyimlerine rastlandığında hazırlıklı olunur. Bu haliyle java diline oldukça benzemektedir. Bu dosya türü ile ilgili daha ayrıntılı bilgilere burada yer vermeyeceğim.

 

COM ve EXE Dosya Biçimleri Arasındaki Temel Farklar

 

DOS için en temel olan program türü COM'dur. COM dosyaları, en fazla 64KB(65536 bayt) büyüklüğünde olabilen; kod, bilgi ve yığına ait tüm içeriği tek bir işlemci segmenti içinde barındıran programlardır. Bir COM programı çalıştırıldığında, program dosyasının tamamı belleğe yüklenir ve tüm segment adresleri, programın segmentini gösterecek şekilde eşitlenir. Program kodu için CS, genel değişkenlere erişim için DS, yığın için ise SS kullanılır ve söz konusu bilgi türlerinin bellekteki yerlerinin kalıcı olmasından ötürü bu yazmaçların değerleri değiştirilmemelidir. Ancak ES, programlar tarafından 1. dereceden önemli bir yazmaç olmadığından program akışı süresince farklı bellek bölgelerine serbest erişim amacıyla değiştirilebilir.

 

COM programları, kesmeler ile yakından ilgilenecek uygulamalar için sıklıkla kullanılır. Kimi zaman DOS kesmeleri, işleve giriş parametresi olarak DS:DX kombinasyonunu kullanırlar ve dolayısıyla DS'nin değiştirilmesi gerekir. Böyle durumlarda, orijinal değerini yığında muhafaza etmek suretiyle DS'nin değeri geçici olarak değiştirilebilir ve dönüşte geri alınabilir. Anlaşılacağı üzere segment yazmaçlarının program boyunca sabit tutulması bir angarya değil, bir önlemdir. Gerekirse SS dahi değiştirilebilir, ancak yığın çok daha tehlikeli bir bölgedir; zira programdan çıkarken ve hatta çıkmadan bilgisayarın kilitlenmesi işten bile değildir.

 

EXE programları ise, gelişmiş tanımlamalar sayesinde daha geniş bellek erişimine ve daha esnek kodlama imkanına sahiptir. Dosyanın toplam boyutu 64K'tan çok daha büyük olabilir. CS, DS ve SS segmentlerinin başlangıç değerleri farklı olabilir ve programın akışı içerisinde farklı bilgilere veya kodlara erişmek amacıyla değiştirilebilir. EXE programlarında kullanılan mantıksal bölmeler ile amaca yönelik olarak farklı ve çok sayıda CS, DS ve SS değeri tanımlanabilir. Tabii ki bu tanımlamaların yapıldığı ekstra bölümler söz konusu olacaktır.

 

EXE programları, bu gelişmiş yapılarından ötürü Debug gibi temel düzeydeki derleyiciler tarafından değil, TASM gibi daha delişmiş derleyiciler ve yüksek seviyeli programlama dillerince kullanılan IDE(Integrated Development Environment)'ler tarafından oluşturulurlar. COM programının oluşturulması, yazılmış olan kodun sayısal karşılığının oluşturularak bir "ikili dosya" içine yazılmasından ibarettir. Debug, bu işlemi yapmak için iki parametreyi kullanır: CS ve yazılacak bayt miktarı. Buna göre belirtilen CS'den itibaren bellek üzerinde belirtilen miktarda bayt dosyaya yazılır ve işlem sona erdirilir. Ancak EXE dosyalarının oluşturulması iki aşamada gerçekleşir: Kaynak kodun derlenerek nesne kodunun oluşturulması(derleme, compilation) ve nesne kodundan, gerekli dış kaynaklarla bağlantı kurularak EXE dosyasının oluşturulması(bağlama, link). Derleme, kaynak kodun içeriğinin belli kurallar ve mantıklar çerçevesinde işlenerek (assembler koduna eş olacak biçimde) .obj dosyasının oluşturulmasını teşkil eder. Ancak bağlama işlemi, çok daha özel işlemler gerektirir ve yeni bilgilerin sentezlenmesini sağlar. Bu konulara daha sonra değineceğim.

 

Her iki türlü programın da denetlenebilmesi ve gerekli parametrelerin sağlanması amacıyla DOS, bir program belleğe yükleneceği sırada PSP(Program Segment Prefix) adı verilen bir ön bölge oluşturur ve gerekli bilgileri yazar. PSP'yi bir başlık altında ele almakta fayda görüyorum.

 

PSP (Program Segment Prefix) ve Yapısı

 

PSP bölümü, program başlangıcından hemen önce yer alan 256 baytlık bellek kısmıdır. Hatırlanacağı üzere Debug ile program yazılacağı zaman başlangıç IP adresleri her zaman 100h'tır(100h=256). İşte bu durum, PSP'nin yerleşiminden kaynaklanmaktadır. 256 baytlık bölüm, çeşitli alt bölümlerde incelenmekte ve kimi kısımları, programcı tarafından kullanılmaktadır. Aşağıda sizlere her iki program türü için de PSP'nin yerleşim şemasını ve içeriğini sunuyorum.

 

COM Programı: CS=DS=SS=ES

Öğe

Başlangıç

Bitiş

PSP

CS:0000

CS:00FF

Kod + Veri

CS:0100

CS:???? (Yığın sonu)

Yığın

CS:FFFF

CS:????

 

Unutulmaması gereken kavramlardan biri, yığının içeri doğru büyümekte olduğudur. Yığına atılan her bilgi, SP'nin azalmasına yol açmakta ve dolayısıyla Kod + Veri bölümüne yaklaşmasına neden olmaktadır.

 

EXE Programı: CS!=SS!=DS, ES=DS

Öğe

Başlangıç

Bitiş

PSP

DS:0000

DS:00FF

Kod

CS:IP (EXE başlığından)

????

Veri

DS:0000

????

Yığın

SS:SP (EXE başlığından)

????

 

Dikkat edilecek olunursa, EXE programındaki PSP'nin yerleşimi CS üzerinde değil, DS üzerindedir. Bu noktada bilgi çakışması yoktur çünkü asıl veri bölümü, kod bölümünün ardına yerleştirilmektedir. DS geçici olarak bu konumu göstermektedir.

 

PSP(Program Segment Prefix)'nin Yapısı

Adres

Öğe

Uzunluk

00H

20 no'lu kesme çağrısı (INT 20H)

2 bayt

02H

Program için ayrılan belleğin segment adresi

2 bayt

04H

Ayırılmış

1 bayt

05H

21 no'lu kesme vektörüne* doğrudan çağrı

5 bayt

0AH

Program sonlandırma kesme vektörünün* (INT 23H)önceki içeriği

4 bayt

0EH

Ctrl-C & Ctrl-Break kesme vektörünün* (INT 23H) önceki içeriği

4 bayt

12H

Kritik hata kesme vektörünün* (INT 24H) önceki içeriği

4 bayt

16H

Ayırılmış

22 bayt

2CH

Ortam değişkenleri tanıtım bölgesinin segment adresi

2 bayt

2EH

Ayırılmış

46 bayt

5CH

FCB 1**

16 bayt

6CH

FCB 2**

16 bayt

7CH

Ayırılmış

4 bayt

80H

Komut satırındaki karakter sayısı

1 bayt

81H

Komut satırı (CR-LF*** ile sonlandırılır)

127 bayt

 

*Kesme vektörü(interrupt vector) bir programcılık deyimi olup, belli bir numaraya haiz olan kesmenin içeriğinin bellekteki yeridir. Kesme vektöründe, söz konusu kesmeye ilişkin alt programın uzak çağrı adresi bulunur(CS:IP biçiminde). Kesmelerin bellekteki yerleri numaralarına göre sabit olup, N kesme numarasını temsil etmek üzere şu şekilde hesaplanırlar: 0000 : N * 4

**FCB(File Control Block), DOS tarafından kullanılan dosya denetim öğesidir. Bu şekilde dosya erişimi sağlayan INT 21H işlevleri bulunur.

***CR-LF(Carriage Return, Line Feed) metin denetimlerinde satır başı ve yeni satır eylemlerini ifade eder. Standart olarak ASCII 10# ve 13# numaralı karakterler ile temsil edilirler.

 

“Ayırılmış” sıfatı ile belirtilen alanlar, geleceğe yönelik olarak işlevlendirilmek üzere bekletilen konumlar veya Microsoft tarafından açıklanmayan bilgilerdir. Yine de varolan bilgilerin bile pek çoğunu kullanmak gerekmeyebilir.

 

Bağımsız bir program yazan programcı için en önemli olan bölüm, 80H adresinden itibaren gelen bölümdür. Assembler programcısı, programına aktarılan parametreleri buradan öğrenir ve gerekli parçalara ayırarak değerlendirir. Ancak C/C++ gibi yüksek seviyeli programlama dilleri, programa aktarılan parametrelere erişim ile ilgili yapısal işlevler içermektedir:

 

int main(int argv,char *argc[])

 

Yukarıdaki tanımlama, standart C++ main işlevinin parametreleridir ve komut satırı parametrelerine erişim sağlamak amacıyla kullanılırlar. Ancak Windows altında programlama yaparken kullanılan WinMain işlevinin, bu erişime yönelik tek parametresi bulunur: LPSTR lpszCmdLine. Bu parametre, PSP'deki 81H adresi ile gösterilen bellek gözünü işaret eder. Parametrelerin ayrıştırılmasından yine programcı sorumludur.

 

Önemli Not: Komut satırı olarak ifade edilen bölüm, programın çalıştırılması için yazılan dosya adını da kapsar. Hatırlanacağı üzere komut satırında bir kerede yazacağınız karakter sayısında sınırlama bulunur. İşte bu sınırlamanın sebebi, PSP'deki komut satırı alanının 127 bayta sınırlı olmasıdır.

 

2CH alanında yer alan ortam değişkenleri tanıtım bölgesinin segment adresi, komut isteminde sadece SET yazarak öğrenilen ve gerektiğinde SET [ifade=değer] biçimde ekleme yapılabilen bilgilerin bellekteki yerini göstermektedir. PATH, COMSPEC, PROMPT gibi önemli sistem parametreleri burada tanımlanmıştır. Mesela eskiden DOS altında çalışan bilgisayar oyunları ve ses uygulamaları, ses kartına doğru şekilde erişmek için gerekli parametreleri, BLASTER* değişkeninin değerini okuyarak öğrenirlerdi.

 

*BLASTER değişkeni, ses kartı kurulum uygulaması tarafından AUTOEXEC.BAT içinde genellikle "SET BLASTER=A220 I5 D1 T5" şeklinde tanımlanır.

 

PSP alanının geri kalan kısmı ile DOS işlevleri ilgilenir. Bu parametrelerin programcı tarafından değiştirilmesi, sistemin kilitlenmesine yol açabilir. Bu bölgede belirtilen parametrelere erişmek amacıyla yine kimi DOS işlevleri mevcuttur.

 

COM Programlarının Özellikleri

 

COM programları, belleğin sabit disk üzerindeki görüntüsünü temsil etmektedir ve çalıştırıldıkları anda dosyanın tamamı geleneksel belleğe(Conventional Memory - programların herhangi bir bellek yöneticisi kullanmaksızın serbestçe erişebildikleri RAM bölümü) yüklenir. Bu yükleme esnasında uygulanan kural, yükleme yapılan belleğin başlangıç adresinin 16 ile bölünebilen bir sayı olmasıdır. Zaten Segment:Offset ifadesinde offset bölümünün 0 olması durumunda efektif adres hesabı ile bulunacak son değer 16 ile bölünebilecektir(EA = (Segment x 16) + Offset). Yerleşim de bu duruma göre normalize edilir; yani IP 0 yapılır.

 

COM programının belleğe yüklenmesinin ardından tüm segment yazmaçları(CS, DS, SS ve ES) PSP'nin başlangıcını gösterir ve herhangi özel bir işlem yapılmaksızın programın çalıştırılmasına geçilir. Normalde SP=0000H iken, yığına 0000H değeri atılır ve SP=FFFEH olur. Bu sıfırlar, son RET komutu ile program bitirilirken, komutun IP'ye yeni değer olarak 0000H yüklemesini ve programın PSP'nin başından itibaren çalışmaya devam etmesini sağlamaktır. PSP'nin başında bulunan INT 20H komutu, DOS'a geri dönüşü sağlar(INT 21H (AH=00H), INT 21H (AH=31H) ve INT 21H (AH=4CH, AL=Çıkış kodu) kesme çağrıları da DOS'a dönüş sağlayan diğer işlevlerdir).

 

COM programları yazılırken kod ve verinin yerleşim şeklini tamamen programcı belirler. Şu bir gerçektir ki programın çalıştırılması anında, geçerli segment ile adreslenecek belleğin tamamı (64KB) programa tahsis edilmiştir ve istenilen biçimde kullanılabilir. Ancak bu belleğin sonunun yığın olarak kullanılması gerekir(mecburiyet yoktur, ancak en iyisi budur). Kod-veri sıralamasında ise izlenecek yol, önce kodun tamamı, sonra veri biçimindedir. Genel programcılık mantığında yığın kullanımının 4 amacı vardır:

Yukarıdaki 4 gerekçenin sağlanması, yığının boyutunun çok büyümesini gerektirmeyebilir. Ancak bir COM programında CS=DS=SS olmasından ötürü kimi zaman programın boyutunun çok büyük olması, kimi zamansa yığına yapılacak aşırı yüklemeler, program kodunun ve/veya genel verilerin yığın tarafından ezilmesine yol açabilir ve bu durum en azından programın görevini doğru biçimde gerçekleştirememesine neden olabilir. Bu nedenle yığının boyutu programcı tarafından sınırlandırılmalı ve kod-veri-yığın sınırı kesinleştirilmelidir.

 

Tüm programın sadece 64K'ya sınırlı olmasından ötürü tüm bellek adreslemeleri ve işlev çağrıları yakın*, dallanmalar ise normal** olmalıdır(çok kısa mesafeler için JMP NEAR kullanılabilir, ancak zaten kod derleyicisi bunu kendiliğinden algılar). Debug, sizin yazdığınız ibaredeki bu uygunluğu test etmez ve gerekli ikili koda dönüştürür, ancak gelişmiş derleyiciler, FAR ibaresini gördüklerinde hata veya tehlike iletisi verirler. Yüksek seviyeli diller veya IDE'ler aracılığıyla üretilecek çalışabilir kodun COM biçiminde olması istendiğinde bellek modelinin Tiny olarak belirtilmesi gerekir.

 

*Yakın Çağrı(CALL NEAR): Çağrı komutunun sadece IP değerini parametre olarak kabul edeceğini bildirir. Dolayısıyla bu komut 3 bayt uzunluğunda olacaktır(CALL xxxx = E8 xx xx).

*Yakın Bellek Adreslemesi(NEAR POINTERS): Herhangi bir bellek gözünü göstermek için sadece işaretçi yazmaçlarının(SI, DI, BX, BP, SP) kullanılmasıdır.

**Normal Dallanma(NORMAL JUMP): Herhangi bir kod bölümüne erişmek için sadece [-32768,32767] bayt aralığında IP değişiminin sağlanmasıdır. JMP NEAR xxxx, derleyici tarafından mesafe göreceli dallanmaya dönüştürülürken, JMP xxxx komutu mutlak biçimde ifade edilir; yani kod içinde xxxx değeri olduğu gibi geçer. JMP NEAR komutu 2 bayt uzunluğundadır, ancak normal bir dallanmanın uzunluğu 3 bayttır.

 

Bir COM programının boyutunun en fazla 64K olabileceği ve bellekte de ancak bu kadar yer işgal edebileceği gerçeğine rağmen, bu tür herhangi bir program çalıştırılırken varolan geleneksel belleğin tümü, DOS tarafından bu programa tahsis edilir ve diğer uygulamalar tarafından kullanılması önlenir. Dolayısıyla geçici bir israf söz konusu olur ve bu uygulamanın TSR(Terminate and Stay Resident - Bit ve Etkin Kal) biçiminde bellekte kalıp da DOS'a geri dönmesi durumunda bile herhangi başka bir program çalıştırılamaz. Bu durumu önlemek için "bellek yönetimi" ile ilgili DOS işlev(ler)i aracılığıyla kullanılmayan belleğin serbest bırakılması gerekir. Eğer serbest erişim yöntemi ile 64K'lık segment dışında herhangi bir bölgede bilgi barındırılmayacaksa, ayırılmış bölgenin sadece programa ait segmentin tamamı olarak belirtilmesi yerinde olur. Hatta program segmentinin içinde herhangi bir bölgenin de serbest bırakılması mümkündür, ancak programın bu bölgede bilgi saklamadığından emin olunmalıdır.

 

EXE Programlarının Özellikleri

 

EXE dosya biçimi, genellikle COM programlarına göre daha büyük ve kapsamlı uygulamalar için kullanılır. Toplam bellek miktarı sadece 64K'ya değil, bilgisayarın sahip olduğu belleğin büyüklüğüne bile sınırlı olmayabilir. Dolayısıyla çok uzun kodlar ve çok büyük miktarda statik(durağan) ve/veya katıştırılmış veriler içerebilir. Ancak bu üstünlükler, iç yapının karmaşıklığını da beraberinde getirmektedir. Çünkü DOS tarafından ihtiyaç duyulan yeni bilgi yapılarına(EXE başlığı) gereksinim duyulacaktır.

 

Bir EXE programı, kullanıcı tarafından çağırıldığında DOS tarafından diskten okunur, belleğe aktarılır ve DOS işlevlerinden INT 21H (AH=4BH) EXEC işlevine ulaştırılır. Bu işlev, dosyanın başında yer alan bilgiler tarafından teşkil edilen EXE Başlığı(EXE File Header) 'nı işler ve programı çalıştırılmaya hazırlar. Aşağıdaki tablo, bu bilgilerin yerleşimini göstermektedir:

 

EXE Başlığı(EXE File Header)'nın Yapısı

Adres

Öğe

Uzunluk

00H

EXE program tanımlayıcısı (HEX: 5A4DH, ASCII: MZ)

2 bayt

02H

Dosya boyutunun 512'ye bölümünden kalan

2 bayt

04H

Dosya boyutunun 512'ye bölümü

2 bayt

06H

Aktarılacak segment adresi sayısı

2 bayt

08H

Paragraf* cinsinden başlık boyutu

2 bayt

0AH

Gerekli en az paragraf* sayısı

2 bayt

0CH

Gerekli en çok paragraf* sayısı

2 bayt

0EH

Yığın bölümü yerleşimi

2 bayt

10H

Program başlangıcında SP'nin değeri

2 bayt

12H

EXE başlığına dayalı kontrol bilgisi(checksum)

2 bayt

14H

Program başlangıcında IP'nin değeri

2 bayt

16H

EXE dosyasında başlangıç CS değeri

2 bayt

18H

EXE dosyasında yerleşim tablosu adresi

2 bayt

1AH

Dosya tümleşim numarası

2 bayt

1CH

Tampon bellek

??

??

Yerleşim tablosu (Adresi 18H'taki bilgiden, boyutu 06H'tan okunur)

??

??

Program kodu, veri ve yığın (Adresler, yerleşim tablosundan öğrenilir)

??

 

Paragraf: Programcılıkta 16 baytlık büyüklüğe verilen ad.

 

EXEC komutu, tüm bu bilgileri değerlendirerek kullanılacak olan öğelerin yerlerini ve yerleşim hedeflerini tespit eder, daha sonra da bu bilgileri hedeflerine yazar. Dolayısıyla programın çalıştırılmaya başlamasından önce yapılan bir dizi iş, programın başlangıcını geciktirerek COM dosya biçimine göre bir zayıflık oluşturur.

 

EXE programının belleğe yerleştirilmesinde yine 16'ya bölünebilirlik şartı vardır, ancak bu sefer IP'nin sıfır (0) olma mecburiyeti söz konusu değildir.

 

Bu yazı dizisinin 3. bölümünde "Model" başlığı altında 6 farklı bellek yerleşimine yer vermiştim. Sadece Tiny modeline ait bellek yerleşimi COM programına uygundur. Bunun dışında kalan tüm modeller EXE program biçimi içindir. Zira söz konusu modellerin tamamında, farklı amaçlar için en az iki farklı segment kullanılmış ve programın kapsamı artmıştır. Ancak bu segmentlerin farklılığı, çeşitli alt programlara ve bilgilere erişebilmek için uzak çağrıları* ve uzak adreslemeleri* gerekli kılar. Kimi dallanmalar da bu durumdan etkilenerek uzak dallanma** olabilir. Bu bellek yerleşimleri hakkında fikir edinmek ve segment sayısının tespiti için 3. bölümü incelemenizde fayda görüyorum.

 

*Uzak Çağrı(CALL FAR): Çağrı kodunun hem IP, hem de CS değerini parametre olarak kabul edeceğini bildirir. Bu şekilde kullanım, komutun 5 bayt olmasına neden olur(CALL FAR xxxx:yyyy = 9A yy yy xx xx)

*Uzak Bellek Adreslemesi(FAR POINTERS): Erişilmek istenen veriye hem işaretçi yazmaçlarının(SI, DI, BX, BP, SP), hem de segment yazmaçlarının(CS, DS, SS, ES) kullanılarak erişildiği yöntemdir. Bu şekilde erişim için toplam 4 baytlık adres kullanılır.

**Uzun Dallanma(LONG JUMP, JMP FAR): Herhangi bir kod bölümüne erişmek için hem CS'nin, hem de IP'nin değiştirilmesidir. Derleyicilerde JMP komutunun ardından FAR ibaresine yer vermek gerekmez; zira dallanılacak olan adres aynı segment içerisinde erişilebilir ise, kodun performansını üstün ve boyutunu küçük tutmak adına derleyici, ifadeyi normal dallanma olarak değerlendirir. Normal dallanma ifadeleri 3 bayt uzunluktayken, uzun dallanma ifadeleri 5 bayttır.

 

Program başlangıcında DS ve ES segmentleri, PSP'nin başını gösterecek şekilde ayarlanır(DS:0000 veya ES:0000 konumu). Ancak CS ve SS'nin başlangıç değerleri EXE başlığından öğrenilir. Program akışı açısından IP ve SP'nin mutlak önemi, bu yazmaç değerlerinin de önceden belirtilmesini mecbur kılar. Ancak DS tarafından sahiplenilen SI ve DI yazmaç değerlerini önceden belirtme ihtiyacı duyulmaz; zira ihtiyaca yönelik olarak bu değerler kullanıcı tarafından serbestçe değiştirilebilmektedir. DS'nin ve ES'nin başlangıç konumu itibariyle, erişilmek istenen genel değişkenlerin bulundukları segment adresi farklı olabilir. Bu nedenle yakın adresleme ile erişim amacıyla bu segment adreslerinin değiştirilmesi gerekebilir.

 

EXE başlığında yer alan minimum paragraf sayısı ve maksimum paragraf sayısı alanları, bu program için gerekecek bellek miktarının EXEC komutu tarafından kestirilmesini ve bellek ayırma işleminin buna göre yapılmasını sağlar. Söz konusu alanlar, bağlayıcı tarafından değil derleyici tarafından belirlenir. Ayrıca segment sayısı, tampon bellek gibi öğeler de buna yardımcı olur. Ancak yine de DOS, COM'da olduğu gibi varolan belleğin tümünü bu program için ayırır ve başka uygulamaların kullanmasına izin vermez. EXE programlarının içinden başka programların çağırılması sıkça karşılaşılan bir durum olduğundan, kullanılmayan belleğin serbest bırakılması gerekir. Bunun için, COM programlarında olduğu gibi DOS'un bellek yönetim işlevlerinden faydalanmak gerekir. Bir EXE programının başlangıcı PSP'nin başı, bitimi ise başlıkta belirtilen SS:SP'dir. Bu sayede programın kullanacağı belleğin yeri ve miktarı kolayca tespit edilebilmektedir. Bellek yönetim işlevlerine gerekli parametreler geçilerek sadece ihtiyaç duyulacak belleğin ayırılması, bunun dışında kalan kısmın ise serbest bırakılması sağlanabilir.

 

Önemli Not: DOS API'de bellek yönetimi 48H, 49H ve 4AH işlevleri ile gerçekleştirilir. Bu işlevler, birim bellek olarak paragraf(16 bayt) büyüklüğünü kullanırlar. 4BH, 4CH ve 4DH işlev ve alt işlevleri ise programların çalıştırılması ve sonlandırılması ile ilgili işlevlerdir(İşlev xx Alt işlev yy : INT21H, AH=xx, AL=yy).

 

Böylece epey uzun sürede bitirebildiğim bu bölümün sonuna geldik. Bu bölümde bellekteki farklı segmentlerin DOS tarafından neden ve nasıl kullanıldığına değinmeye çalıştım. Aynı zamanda, komut isteminin de aslında çalışmakta olan bir program olduğunu, sizin yazdığınız komutları yorumlayarak ne yapmak istediğinizi anladığını ve gerekirse yeni bir programı diskten belleğe alıp, gerekli sürecin ardından çalıştırdığını göstermek istedim. Bu konuda çeşitli noktalarda kaynak olarak kullandığım "PC INTERN" kitabının da hakkını vermeden geçemeyeceğim. Sanırım bir dahaki bölüm 32-bit assembler ve 32-bit kipler ile ilgili olacak. Sağlık ve sevgiyle kalın, hoşçakalın...

 

Cihan Atıl Namlı

 

6 Aralık 2004 Pazartesi, 14.30