|
Pekala, Linux'ta grafik işleri için pekçok araç vardır. Hangisini kullanacağınız ne yapmak istediğinize bağlıdır. Tüm bilgilere sahip bir web sayfası yoktur ama işte bir kaç püf nokta: SVGALib: Bu, konsoldan SVGA erişimi için C kütüphanesidir. Artıları: öğrenmesi kolay, iyi kodlama örnekleri, DOS'taki gfx kütüphanesinden pek de farklı değil, DOS'taki tüm etkiler az bir değişiklikle dönüştürülebilir. Eksileri: program doğrudan donanıma eriştiği için, çalışmak için root erişim yetkilerine gerek duyar, her çip (chipset) ile çalışmaz, X-Windows altında çalışmaz. http://ftp.is.co.za'da svgalib-1.4.x diye aratın. Framebuffer: SVGA ile ilgili kendinizce yapılabilen grafikler Artıları: hızlı, doğrusal olarak haritalanmış video erişimi, eğer isterseniz ASM kullanılabilir :) Eksileri: çekirdek içinde derlenmeli, çipsete özgün özellikler, çalışması için X kapatılmalı, iyi linux sistem çağrıları ve çekirdek bilgisine dayanır, hata ayıklaması zordur Örnekler: asmutils (http://www.linuxassembly.org), yaprak örneği, framebuffer kodu ve asm ile ilgili ipuçları için benim sayfam (http://ma.verick.co.za/linux4k/) Xlib: XFree86 için uygulama ve geliştirme kütüphaneleri. Artıları: X uygulamanız üzerinde tam bir kontrol Eksileri: Öğrenmesi zor, çalışması korkunç ve az da olsa X'in düşük seviyede nasıl çalıştığı bilgisini gerektirir Tavsiye edilmez, ama onu için bu kadar yanıp tutuşuyorsanız durmayın. Muhtemelen tüm başlık ve kütüphane dosyaları yüklenmiştir, dolayısiyle ihtiyacınız olana sahipsiniz. Düşük seviyeli API'ler: PTC, SDL, GGI ve Clanlib'i içerir. Artıları: çok esnek, X veya konsolda çalışır, video donanımını soyutlar onun için düzgün doğrusal bir yüzey çizebilirsiniz, pekçok güzel örnek kod, OpenGL ve ses kütüphaneleri gibi diğer API'lere bağlantı kurabilir Microsoft DirectX sürümleri özgürdür. Artıları: Kendi yaptığınız kadar hızlı değildir, gelişim sürecince bazen sürümler çok sık değişir. Örnekler: PTC ve GGI mükemmel demolara sahiptir, SDL ise oyunlar için, sdlQuake, Myth II, Civ CTP ve ayrıca Clanlib'de kullanılmıştır. Yüksek seviyeli API'ler: OpenGL - başka var mı? Artıları: temiz API, yüzlerce işlevsellik ve örnek, endüstriyel standart; bundan dolayı mesela SGI'dan öğrenilebilir Eksileri: donanım hızlandırılması normalde bir zorunluluktur, bazı sürümler ve platformlar arasında acayiplikler Örnekler: çokça - bağlantılar bölümü altındaki www.mesa3d.org kısma bakınız. Bakmayı sürdürmek için svgalib örneklerini inceleyin ve aynı zamanda SDL'yı yükleyin ve çalışır duruma getirin. Bundan sonrasında ise limit gökyüzüdür.
Kişisel olarak, gdb'yi asm uygulamarınının hatalarını bulmak için kullanırım. şunu deneyin: 1) Derlemek için aşağıdaki kodu kullanın: $ nasm -f elf -g smth.asm $ ld -o smth smth.o 2) gdb'yi çalıştırın $ gdb smth 3) gdb içinde: (gdb) disassemble _start at _start+1'e bir kesme koyun (eğer at _start konursa çalışmaz, nedenini bilmiyorum) (gdb) b *0x8048075 kodu takip edebilmek için aşağıdaki kodu kullanırım (gdb)define n >ni >printf "eax=%x ebx=%x ...etc...",$eax,$ebx,...etc... >disassemble $pc $pc+15 >end daha sonra programı r parametresiyle çalıştırıp, n ile hata ayıklayın Umarım yardımcı olmuştur.
.gdbinit'imin içinde epeydir kullandığım bir makro var, ve eminim hayatı daha kolay hale getiriyor. Az farkla: "x /8i $pc"' kullanırım bu da belli sayıdaki çevrilmemiş koda müsaade eder. Daha sonra iyi şekilde boyutu seçilmiş xterm'imle gdb çıktısı tazelenmiş olarak ve kaydırma gerektirmeden görünür.
section .text global init_module global cleanup_module global kernel_version extern printk init_module: push dword str1 call printk pop eax xor eax,eax ret cleanup_module: push dword str2 call printk pop eax ret str1 db "init_module done",0xa,0 str2 db "cleanup_module done",0xa,0 kernel_version db "2.2.18",0
$ nasm -f elf -o module.m module.asm $ ld -r -o module.o module.m
ebx := 0 (in fact, any value below .bss seems to do) sys_brk eax := current top (of .bss section) ebx := [ current top < ebx < (esp - 16K) ] sys_brk eax := new top of .bss
section .bss var1 resb 1 section .text ; ;allocate memory ; %define LIMIT 0x4000000 ; yaklaşık 100Megs mov ebx,0 ; data bölümünün en alt kısmını elde et call sys_brk cmp eax,-1 ; tamam mı? je erro1 add eax,LIMIT ; +LIMIT bellek kısmını tahsis et mov ebx,eax call sys_brk cmp eax,-1 ; tamam mı? je erro1 cmp eax,var1+1 ; data bölümü büyüdü mü? je erro1 ; ;tahsis edilmiş alanı kullan ; ; şimdi eax data bölümünün alt kısmını ; barındırır mov ebx,eax ; alt kısmı kaydet mov eax,var1 ; eax=data bölümün başlangıç kısmı repeat: mov word [eax],1 ; 1'lerle doldur inc eax cmp ebx,eax ; şu anki pozisyon = en alt? jne repeat ; ;belleği serbest bırak ; mov ebx,var1 ; belleği geri ver call sys_brk ; başlangıcını=var1 yaparak cmp eax,-1 ; tamam mı? je erro2
sys_open'ı çağırdığınız zaman, sürecinizle ilgili açık olan tüm dosya tanıtıcılarının olduğu bir tablodan bir indis olarak, bir dosya tanıtıcı döndürür. stdin, stdout ve stderr için sırasıyla 0, 1 ve 2'dir, çünkü bunlar süreciniz için her zaman açık durur. Aynı zamanda ilk açtığınız dosya tanıtıcısının 3 olocağını ve artacağını unutmayın. İndislemeyi anlamak select'in ne yaptığını anlamanızı sağlar. select'i çağırdığınız zaman, okumak için, yazmak için, istisnai durumları belirlemek için belli bir dosya tanıtıcısını beklediğinizi belirtiyorsunuzdur. Süreciniz 1024 açık dosya tanıtıcısına sahip olabilir, dolayısiyle fd_set sadece bir bit maskesi gibi çalışarak hangi dosya tanıtıcısının hangi işlem için geçerli olduğunu belirtir. Bir şeyler ifade etti mi? Her açtığınız fd birer indis olduğu için, her bir fd_set için on veya off olmaya ihtiyacı vardır, sadece 1024 bitlik bir fd_set yapısına ihtiyacınız vardır. Yapıyı belirtmek için 1024 / 32 = 32 long gereklidir. Şimdi basit bir örnekle açıklayalım. Farzedelimki dosya tanıtıcıyı okumaya çalışıyorsunuz (zamanaşımı olmadan). - fd_set'e belleği tahsis et .data my_fds: times 32 dd 0 - okumak istediğiniz dosya tanıtıcıyı açın - fd_set yapısındaki bitini ayarlayın Öncelikle, 32 dwords'ün hangisinde bitin olduğunu belirlemelisiniz. Daha sonra, bts'yi kullanarak bu dword içindeki biti ayarlayın, bts biti 32'ye bölümden kalana göre ayarlayacaktır. Bu da önce hangi dword ile çalışmaya başlamanızı belirlemenin sebebidir. mov edx, 0 mov ebx, 32 div ebx lea ebx, my_fds bts ebx[eax * 4], edx - son adımı okumak istediğiniz dosya tanıtıcılar için yineleyin - belli bir eylem beklediğiniz diğer iki fd_set'in herbiri için de tüm örneği tekrarlayın Bundan, geriye denklemin diğer iki parçası kalır - n parametresi ve zaman aşımı parametresi. Zaman aşımı parametresini okuyucuya örnek olarak bırakıyorum (evet, tembelim), fakat kısaca n parametresiyle ilgili konuşacağım. Bu, seçtiğiniz dosya tanıtıcıları içerisindeki en büyük değere sahip olanın değeri (herhangi bir fd_set'ten) artı birdir. Neden artı bir? Çünkü, bu değerden maskeyi belirlemek kolaydır. Farzedin ki x dosya göstericisi üzerinde bir veri var, fakat sizin ilgilendiğiniz en yüksek olan (n-1). fd_set sadece bir bit maskesi olduğundan, çekirdeğin select'en geri dönmesi veya dönememesi için verimli bir yola ihtiyacı vardır. Dolayısiyle, bu, ilgilendiğiniz bitleri maske dışında bırakır, halihazırda atanmış bitlerde herhangi bir değer var mı diye kontrol eder, eğer varsa geri döner. Aslında, fantastik olduğunu söylemek düşündüğüm kadar kolay değil. Çekirdeğin bu maskeyi nasıl belirlediğini görmek için, çekirdek kaynak ağacındaki fs/select.c'ye bakınız. Herneyse, bu numarayı bilmeye ihtiyacınız vardır, en kolay yol da açılmış olan en son dosya tanıtıcının numarasını bir yerlere kaydetmektir. Evet, bildiklerim bunlar. Yukarıdaki kodla ilgili uyarı (her zaman ki gibi) şu: test edilmemiştir. Sanırım çalışır, eğer çalışmazsa beni haberdar edin. Fakat, eğer evrensel bir nükleer felakete sebep olursa, o zaman aramayın. ;)
|