Bölüm 1: Debug ile 80286 Kodu Yazmak ve Çözümlemek

 

Windows ortamında veya açılışta F8'e basarak DOS'a çıktığınızda 80286 komutları ile denemeler yapabileceğiniz bir program mevcut: Debug. Debug ile COM programları yazabilir ve kaydebilir, daha sonra istediğiniz zaman kullanabilirsiniz. Dahası, yazılmış olan bir COM programının içeriğini(kaynak kodunu) görüntüleyebilirsiniz. Bunlar nasıl mı yapılır? Okumaya devam...

 

Terim anlamıyla "Debug", hata ayıklamak anlamına gelir ve uzman programcıların, programı normal şekilde çalıştırmadan önce "Step by step" (Adım adım) ilerleterek, yazdıkları kodun herhangi bir yerde patlayıp patlamayacağını görmelerini sağlar. Tüm IDE (Integrated Development Environment) programlarında bulunan bir özelliktir. Konu dağılıyor, geri dönelim...

 

Komut satırında "debug" yazarak Enter'a bastığınızda bir tire (-) ardında imlecin yanıp söndüğünü görüyorsanız, işler yolunda demektir. Yani:

 

C:\>debug

-

 

Pratik yapmak amacıyla kod yazmak istiyoruz. Bunun için "a" yazıp Enter'a basacağız. Artık ekranda xxxx:0100 yazıyor ve imleç yanıp sönüyor. Burada xxxx, DOS tarafından size atanmış olan kod segment adresidir. Bunun ne olacağını evvelden kestiremezsiniz, ancak zaten herşey göreceli olduğundan bunu bilmenin bir önemi yoktur. Dahası, bir COM uygulaması çalıştırıldığında CS=DS=SS=ES olur ki, bunun nedenini merak etmeniz için çok erken. İlk IP adresinin neden 0100 olduğunu merak etmeniz için daha da erken. İşimize bakalım ve şimdi hep birlikte bir deneme yapalım, aşağıdaki kodu girelim(her satırın ardından Enter'a basmayı unutmazsınız herhalde, ayrıca satırın tamamını değil, assembler deyimlerini yazın):

 

C:\>debug
-a
1586:0100 mov ax, 12df

1586:0103 mov bx, d76a

1586:0106 add ax, bx

1586:0108 ret

1586:0109

-

 

Yukarıdaki 5 satır, siz kod yazıp Enter'a bastıkça IP adresinin ilerlemesi ile devam edecektir. Geçersiz bir deyim veya kombinasyon yazarsanız, IP adresi değişmeksizin ^Hata yazar ve bir alt satırdan devam eder. Eğer yazığınız kodun tamamlandığını düşünüyorsanız, bulunduğunuz satırda deyim yazmadan Enter'a basın, yeniden programı ilk çalıştırdığınız konuma geri dönmüş olacaksınız. Mesela yukarıda 1586:0109 adresini belirten satırda artak yazacağımız birşey olmadığını düşündüğümüzden böyle yapıyoruz ve yine tireyi (-) görüyoruz.

 

Şimdi bu programı çalıştırmak istiyoruz. Yapacağımız iş, bu konumdayken adım adım ilerlemeyi sağlamak için "p" yazıp Enter'a basmak. Her basışımızda şunları göreceğiz:

 

-p

 

AX=12DF  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000

DS=1586  ES=1586  SS=1586  CS=1586  IP=0103   NV UP EI PL NZ NA PO NC

1586:0103 BB6AD7        MOV     BX,D76A

-p

 

AX=12DF  BX=D76A  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000

DS=1586  ES=1586  SS=1586  CS=1586  IP=0106   NV UP EI PL NZ NA PO NC

1586:0106 01D8          ADD     AX,BX

-p

 

AX=EA49  BX=D76A  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000

DS=1586  ES=1586  SS=1586  CS=1586  IP=0108   NV UP EI NG NZ AC PO NC

1586:0108 C3            RET

-p

 

AX=EA49  BX=D76A  CX=0000  DX=0000  SP=FFF0  BP=0000  SI=0000  DI=0000

DS=1586  ES=1586  SS=1586  CS=1586  IP=0000   NV UP EI NG NZ AC PO NC

1586:0000 CD20          INT     20

-p

 

Program normal olarak sonlandırıldı

-

 

Sanırım hepiniz anlamışsınızdır, her "p" yazıp Enter'a bastığımızda işlenen satır sonucunda tüm CPU yazmaçlarındaki yeni değerler ekrana yazılmaktadır. NV UP EI vs... şeklinde giden ibareler ise bayrakları temsil etmektedir. Bir alt satırda yazan yeni kod ise, siz yeniden "p" yaptığınızda işlenecek olan deyimdir. Şimdi dikkatinizi bir noktaya çekmek istiyorum. Siz en son "ret" yazarak kodunuzu sonlandırdınız. Ancak bu deyimin işlenmesinin ardından "INT 20" diye yeni birşey daha gelmiş. "Bu da neyin nesi? Ben böyle birşey yazmadım." diyenleriniz mutlaka vardır. Bu, 20H kesmesi, yani DOS'a geri dönüş fonksiyonudur. Siz yazmasanız da debug, bunu işleme koyar ki asıl ortama geri dönülebilsin. Büyük küçük harf de kafanızı karıştırmasın; assembler dili bu konuda duyarlı değildir(Non-case sensitive).

 

Burada tek bir sorun var: Yazdığınız bu kodu "p" komutuyla bir kez çalıştırdıktan sonra yeniden aynı aşamaları görme şansınız olmuyor. Bunun için, yazmış olduğunuz kodu kaydetmekte fayda var. Burası incelikli bir nokta. Dikkat edelim ve anlamaya çalışalım.

 

Kodu yazıp da başlangıç konumuna geri döndüğümüzü düşünelim. Şimdi kaydetmek istediğimiz dosyanın adını yazmalıyız. Bunun için "n" yazıp bir boşluk bıraktıktan sonra dosya ismini yazıyoruz ve Enter'a basıyoruz. Mesela "n asm1.com" gibi. Artık debug, oluşturacağı dosyanın adını biliyor. Şimdi dosyaya kaç bayt yazılacağını bildirmemiz gerekiyor. Burası ilk etapta kafanızı karıştıracaktır. Biliyorum, şimdi "Yaa zaten benim yazdığım kod belli, dosyaya ne yazılması gerektiğini söylemişim, neden kaç bayt yazacam diye beni geriyor ki..." diyenler vardır. Debug ve benzeri programlar, CS ile belirtilen segmentteki belleği doğrudan düzenlemenizi sağlamaktadır. Sizin yazmış olduğunuz her kod, aslında belirtilen belleğe yazılan baytlardır. Öte yandan bu belleğin başı sonu da belli değildir. Yani debug olaya yapılan komutlar değil, dosyaya aktarılan bellek olarak bakmaktadır. Dolayısıyla ne kadar belleğin aktarılacağını tamamen siz belirlemektesiniz. Bunu nasıl yapacağız? Şöyle: Debug, dosyaya yazma işlemindeki bayt miktarını o anki CX yazmacından okur. Çok garip, CX'de ne varsa o kadar yazıyor. O halde programı yazıp da bitirdikten sonra CX'e bu değeri yazmalıyız. "r" komutu, o anki yazmaç değerlerinin tamamını ekranda görüntüler. Ama eğer "rxx" gibi eklentili bir kullanımda bulunursak, xx diye belirttiğimiz yazmaca istediğimiz değeri yazmamızı sağlar. "rcx" yazarak CX yazmacına, yazılmasını istediğimiz bayt miktarını girebiliriz. Unutulmaması gereken tek şey ise, debug programının her yerinin hex sayılar ile çalıştığıdır. Yani 100 bayt yazmak istersek 64 girmeliyiz. Bu işlemi de hallettikten sonra geriye tek şey kalır: Yazma komutunu vermek. Bunun için de "w" komutu kullanılır. Siz bu komutu verdiğinizde ekranda "xx bayt yazılıyor" diye bir ibare belirir. Artık dosya kayıt işlemi tamamlanmıştır. Programdan tamamen çıkmak için ise "q" komutunu kullanabiliriz.

 

Eğer mantıklı ve/veya işe yarar bir program yazdıysanız, bu programı defalarca kullanabilirsiniz. İşin güzel yanı ise, COM uzantılı programların çok küçük boyutlu olmaları. 200-300 bayta ciddi anlamda iş yapan programlar yazabilirsiniz. Unutmayın: 378 numaralı port Paralel port, 2F8 ve 3F8 numaralı portlar ise seri portlardır. Çok basit mikroişlemci kodları ile bu portlara erişebilir, bilgi okuyabilir ve gönderebilirsiniz. 21 numaralı kesme DOS fonksiyonları içerir ve çok basit işlemler ile dosyaları açabilir ve okuyabilirsiniz. Ama daha erken!..

 

Aşağıda başka bir kullanım şekli yer alıyor.

 

C:\>debug [COM dosyası]

 

Bu şekilde [COM dosyası] dizesinde belirtmekte olduğunuz COM dosyasını açmış olursunuz. Korkmayın, bu işlem dosyayı bozmaz. Ayrıca "win.com" dosyasını açıp da içini okumak da size birşey sağlamaz. Buradaki amaç, en fazla 1KB boyutundaki özel amaca yönelik COM dosyalarının içeriğini okumak olmalıdır.

 

Bu şekilde dosyayı açtıktan sonra yine tireyi (-) takiben imlecin yanıp söndüğünü göreceksiniz. Bu konumdayken "u" yazıp Enter'a bastığınızda xxxx:0100 adresinden itibaren dosyanın assembler içeriğinin döküldüğünü göreceksiniz. 10-20 satır döküldükten sonra işlem duracak ve yine imleç yanıp sönecektir. Her seferinde "u" yazıp Enter'a basarak dosyanın devamını da görüntüleyebilirsiniz. Bu şekilde kullanım, kendinizi henüz kod yazmaya hazır hissetmediğinizde biraz cesaret kazanmak için yapılabilecek iyi bir iştir.

 

Bu bölümün sonuna geldik. Bunu yazmak yaklaşık 2 saatimi aldı ve bir nikaha gitmek için yarıda kesmiştim. Eve gelip tamamladım. Galiba yazdıklarımda yanlışlık yok ama insanlık halidir, deneyip de hata bulursanız bildirin. Mümkünse canımı okumadan olsun. Bir de, bu mikroişlemci işi adamı hem sarıyor, hem gıcık ediyor, hem de beynini yiyor. Eğer illa da "Ben bu konuda uzmanlaşacağım" derseniz bana da bildirin de birkaç yol yordam anlatayım, sonra bilgisayarın başında boynunuz tutulmasın. Saat 21.05, Türkiye-Gürcistan maçının 2. yarısı başladı, başlayacak. İlk yarısını kaçırdım, ikinciyi seyredeceğim. Biraz sonra da arkadaşım kapıyı çalar, birlikte seyrederiz. Size de iyi eğlenceler dileyecem de, siz bunu okuduğunuzda... geç olur. İkinci bölümde görüşmek üzere...

 

Cihan Atıl Namlı

 

4 Eylül 2004 Cumartesi, 21.05