Bu sayfadaki yazılar
Sayfanın metni
Sayfa 54
Giriş
Merhaba arkadaşlar. Bu yazıda genel bazı hata arama ve bulma tekniklerinden bahsedip, bu tekniklerin özellikle C64 programları geliştirirken nasıl uygulandıklarını göstereceğiz. Bunun için en önemli araçlardan biri olan Vice emülatörünü kullanacağız. Vice emülatörü hem Windows hem Linux'ta çalışan bir araç olduğu için iki platformda Vice'ın farklı olduğu noktaları da belirteceğiz.
Bu yazıda aşağıdaki konular anlatılacak:
Debugger'lara Genel Bakış * Breakpoint'ler Kod'u adım adım çalıştırma Register'ları inceleme * Belleği inceleme Vice Monitörü Örnek kod Monitöre giriş ve çıkış Breakpoint'ler Adım adım ilerlerken register'ları takip etmek C64 Programlarında Sık yapılan hatalar Daha ileri teknikler
Bellekteki değişmeleri yakalamak.
Karmaşık breakpoint'ler
Başkalarının programlarını incelemek.
Debugger'lara Genel Bakış
Her platformda debugger deyince aklımıza gelen bazı ortak noktalar vardır. Genelde yazılan bir programın içinde herhangi bir anda belleğin ve CPU register'larının durumunu sorgulayarak o programın içindeki hataları bulmaya ve gidermeye çalışırız. Debugger'lar çeşitli GUI'ler veya komut konsolu arayüzlerine sahip olabilir. Fakat bazı temel özellikler bütün debugger'larda aynıdır.
- Breakpoint'ler
Bellekte çalışan kodun, herhangi bir noktasına gelince programın duraklamasını isteyebiliriz. Breakpoint'ler debugger'da, bellekteki kodun bir satırına (veya makine dili komutuna) yerleştirebildiğimiz bir araçtır. CPU kodu işletirken, breakpoint ile karşılaşırsa o anda programı dondurup kontrolü bize ve debugger'a verir. Böylece biz debugger'ın çeşitli komutlarını kullanarak register'ların ve belleğin tam o anda sahip oldukları değerleri inceleyebiliriz.
Genelde breakpoint'leri kullanırken aklımızda iki şey vardır:
Birincisi CPU oradan önceki komutları başarıyla işletip bu noktaya gelebiliyor mu, bunu görmek isteyebiliriz. Programımızı yazıp çalıştırdığımız zaman ilk karşımıza çıkan ve yanlış olan belirti, genelde bize nereye bakmak istediğimiz ile ilgili fikir verebilir. Örneğin, programın bir yerde ekrana bir mesaj çıkarmasını bekliyorsak ve bu mesaj çıkmıyorsa, mesajı yazdıran fonksiyonu çağıran yerlere breakpoint koyabiliriz. Programımız o fonksiyonu düzgünce çağırıyor mu? Bazen bu şekilde breakpoint koyup programımızı çalıştırınca CPU'nun durmadığını görür ve anlarız ki program oraya hiç gelmiyor. Ya bir yerlerdeki kontrollü dallanma (if else / je / bne ...) bizim beklediğimiz gibi çalışmıyor, ya da program daha önce bir yerde bir sonsuz döngüde kalıyor.
İkincisi ise eğer program başarıyla breakpoint'e ulaşıp duruyorsa breakpoint'ten sonraki o kritik algoritmamızı yavaş yavaş inceleyebilme isteği. Çoğu zaman bir breakpoint'ten sonra programımızı adım adım çalıştırarak yaptığımız pek çok hatayı buluruz.
Breakpoint'leri öğrendiğiniz anda hata ayıklama sanatının %50'sini öğrendiniz demektir.
- Kod'u
adım adım çalıştırma
Genelde bir algoritmanın tam olarak doğru çalışıp çalışmadığını anlamak için debugger'ın adımlama özelliklerinden faydalanırız. Bütün debugger'larda Step-In, Step-Over ve Return-from-Function denilen üç adım çeşidi her zaman vardır.
Step-In bir seferde bir komut ilerlemenizi sağlar. Bu komut eğer bir alt fonksiyona atlama komutu ise, yaptığınızda gidilen alt fonksiyonun ilk komutunda bulursunuz kendinizi.
Step-Over da bir seferde bir komut ilerlemenizi sağlar. Fakat Step-In'den farklı olarak eğer bir sonraki komut alt rutine atlama komutuysa, Step-Over ile bütün alt fonksiyonu bir seferde çalıştırıp o alt rutin döndükten sonraki ilk komutta bulursunuz kendinizi. Dolayısıyla kodu adım adım ilerletirken detaylı incelemek istemediğiniz bir alt rutin çağrısı ile karşılaşırsanız Step-Over ile vakit kaybetmeden ilerleyebilirsiniz.
Son olarak Return-From-Function komutu ile de o an bulunduğunuz fonksiyon veya rutinin sonuna kadar ilerleyip, o rutini çağıran yere dönebilirsiniz. Bu da genelde bir alt rutini incelemek için içine girdikten sonra aradığınız sonucun o rutinde olmadığını görünce kullanabileceğiniz bir komuttur.
- Register'ları
ve belleği inceleme
Genelde kodda adım adım ilerlerken her komuttan sonra CPU register'larındaki değerleri inceleyerek komutların ve hesaplamaların beklediğiniz sonuçları ortaya çıkarıp çıkarmadığını takip edebilirsiniz. Her debugger CPU register'larındaki değerleri ve belleğin durumunu size gösterecek komutlarla donatılmıştır.
Klavyeyle gezinmek için ← ve → tuşları.
Sayfa 55
Vice Monitörü
Bu kadar genel tanıtımdan sonra yukarıda bahsettiğimiz komutları Vice'da nasıl vereceğimizi inceleyelim. Bu bölümde örnek olarak hatalı bir kod ile başlayacağız. Daha sonra Vice debugger'ını kullanarak hatayı nasıl bulabileceğimizi göreceğiz.
- Örnek kod
Bir bahar akşamı cevval coder adayı Psychadelic/Granite yeni introsunu (Devil is My Friend adlı şaheser olacaktı) kodlamaya başladı. Tabii ki ilk olarak her introsunda olduğu gibi ekrana bir tane raster çizgisi koyarak başlayacaktı. Hemen aşağıdaki kodu yazdı. Birkaç ACME uyarısını atlatıp sonunda kodu derledi. Vice ile açtı. sys 49152... Ve hiçbir şey olmadı.
UYARI: BU KOD BİLİNÇLİ OLARAK HATALAR İÇERMEKTEDİR
” a !to "devil.prg", cbm *—-$c000
A Baslangic: jsr RasterIROHazirla Son:
sei
lda sta
#$7E£ $dc0d
lda ora sta
$d0la #$O1 $d0la
lda and sta
#$7E
lda sta
#$20 $d012
lda sta lda sta
$00 $0314 $el $0315
eli *—-$c100 IRORutini: inc $d019
ldx #$2 IRO gecikme dongusu: dex bne IRO gecikme dongusu
lda $d020 pha lda #$01 sta $d020
ldx $0a IRO gecikme dongusu2: dex bne IRO gecikme dongusu2
lda #$0e sta $d020
jmp
- Monitöre
giriş ve çıkış
Bunun üzerine Psychadelic hemen resetleyip bu sefer sys49152 demeden önce, Alt-M ile monitöre girdi (Linux Alt-H). Artık Debugger konsolu karşısında onun komutlarını bekliyordu.
Şekil 1. Vice Debugger Konsolu
- Breakpoint'ler
Hemen kendine sordu. "Kurduğum interrupt çalışıyor mu? Program interrupt rutinine ulaşıyor mu?" Bunu anlamak için $c100'deki interrupt rutininin başına bir breakpoint koymaya karar verdi. Bunun için konsola şu komutu yazdı: break c100
Ardından kodu çalıştırmak için debugger'dan çıkmaya gerek duymadı ve direkt başlangıç adresine atlama komutu verdi.
g c000
Program breakpoint'te durmadı ve çalışmadı. Psychadelic anladı ki interrupt rutinini doğru kurmuyor. Bunun üzerine programın başına breakpoint koyup interrupt rutinini hazırladığı bölümü tek tek incelemeye karar verdi.
break c000 g c000
İkinci komutu vermesiyle beraber program çalışmaya başlamak üzere c000'a atladı ve oradaki breakpoint'e yakalandı.
- Adım
adım ilerlerken registerları takip etmek z komutunu kullanarak adım adım komutları işletmeye başladı. Vice kullanıcı konsol penceresinde Enter'a her bastığında son debugger komutunu işletiyordu. Bu sayede ilk seferde z komutunu verdikten sonra her Enter'a basışında yeni bir Step-In komutu vermiş oluyordu. Bu komutlar sayesinde program satır satır ilerledi ve her defasında bir sonraki assembly komutunun işletildiğini gördü.