1.bölüm 1.sayı s stemler - Fikir Elektronik Teknik
Transkript
1.bölüm 1.sayı s stemler - Fikir Elektronik Teknik
1.BÖLÜM 1.SAYI SİSTEMLERİ Başka bir gezegeni ziyaret etmedikçe, nesneleri ondalık sayılar kullanarak sayarak hayatımızı geçiririz. Matematikçiler ondalık ifadesini 10 tabanında sayma sistemi olarak değerlendirirler. Çünkü bu 0 ile 9 arasında 10 rakamdan oluşmaktadır. İnsanoğlu ondalık sayılarla daha rahat sayabilmektedir. (Belki de on el ve ayak parmağı olduğu için.) Ama bilgisayarlar böyle değil. Bunun yerine bilgisayarlar 2’lik tabandaki (binary) sayma sistemiyle sayarlar. Bu tabanın yalnız iki rakamı vardır. 0 ve 1. Bundandır ki bilgisayarlar kendi düzeylerinde haberleşirler. (Siz bunu assembler dili kullandığınızda yaparsınız.) İkilik (binary) sayma sistemine alışık olmalısınız. Binary yanında, assembler-dili programcıları bir diğer sayma sitemi olan 16 tabanındaki (hexadesimal) sayma sitemine de iyi derecede alışık olmalıdırlar. Bu bölüm daha önce hiçbir birikimi olmayan okuyucular için bilgisayar sayı sistemlerini ele alır. Eğer zaten binary ve hexadesimal sayma sitemlerini biliyorsanız bu bölümü atlayabilirsiniz. 1.1.İKİLİK (BINARY) SAYMA SİSTEMİ Bir bütün program talimatlarını ve veriyi belleğinden alır. Bellek binlerce elektrikli bileşen içeren tümleşik daireler (ya da yongalar) kapsar. Işık anahtarları gibi bu bileşenlerde yalnız iki olası ayar vardır. “On” ya da “off”. Hala yalnızca bu iki ayarla, bellek bileşenleri kombinasyonları herhangi bir boyutun sayılarınız gösterebilir. Nasıl mı? Okumaya devam edin. Bellek bileşeninin On ve Off ayarları ikilik sayı sisteminin iki rakamıyla uyuşmaktadır. Bu bilgisayarın temel sistemidir. Yalnızca iki rakamımız var. 1 (On) ve 0 (Off). İkilik sayı sistemi bir 2 tabanı sitemidir. Yeniden, bu durum ikilik sayı sistemini 10 rakama sahip (0 ile 9 arasında) standart ondalık sayı sisteminden ayırır. Belleğin anahtara benzer bileşenleri “bits” (binary digits’in kısaltması) diye adlandırılır. Gelenek olarak, bir bit “on” olduğunda 1 değerini “off” olduğunda 0 değerini alır. Bu gösterir ki bir ondalık rakamı (0 ile 9 arasında) düşünene kadar sınırlandırır. Şimdi siz ondalık rakamları 9’dan büyük formda sayılara birleştirebiliyorsanız, binary rakamları da 1’den büyük sayılara birleştirebilirsiniz. Bildiğiniz gibi 9’dan büyük ondalık sayıları göstermek için ek “onlu” rakamlara ihtiyacınız var. Benzer şekilde 99’dan büyük ondalık sayıları göstermek için bir “yüzlü” rakama gerek var ve böyle devam eder. Her ondalık rakam için hemen sağına 10’un katları rakamları eklemelisiniz. 1 Örneğin; 324 sayısını göstermek için (3*100)+(2*10)+(4*1) ya da böyle (3*102)+(2*101)+(4*100) Böylece, her ondalık rakamda 10’un gücü önündeki rakamdan daha büyüktür.Benzer kural ikilik sistemde de uygulanır. Burada her ikilik rakamda ikinin gücü önündeki rakamdan daha büyüktür. En sağdaki bit 20 ‘ın katına sahiptir (Ondalık 1). Sonraki bit 21’nin katına sahiptir (Ondalık 2) ve böyle gider... Örneğin: İkilik 101 sayısı ondalık 5 değerindedir. Çünkü: 1012 = (1*22) + (0*21)+ (1+20) = (1*4) + (0*2) + (1*1) = 510 Binary sayılarının nasıl inşa edildiğini anlayabiliyor musunuz. Verilen herhangi bir bit konumunun değerini bit durumunun öncellenmesinin ağırlığını iki katına çıkarırsınız. Böylece ilk sekiz bitin binary ağırlığı 1, 2, 4, 8, 16, 32, 64 ve 128 olur. Bu durum Şekil 0-1’de gösterilmiştir. 7 6 27 26 128 5 4 25 64 32 3 24 16 2 23 8 1 22 4 0 21 2 BIT KONUMU 20 1 İKİ ONDALIK DEĞERİN GÜCÜ Şekil .1.1 Sekiz ikili rakamın ağırlıkları. Ondalık sayıyı ikilik sayıya çevirmek için bir dizi basit çıkarama işlemi yapın. Her çıkarma prosedürü bir tekil ikilik rakam (bit) değeridir. Başlamak için en büyük olası ikilik ağırlığı ondalık değerden bu bit konumuna “1 girin”. Sonra sonraki en büyük ağırlığı sonuçtan çıkarın ve bu bit konumuna bir “1” girin. Sonuç “0” 2 olana kadar devam edin. Herhangi bir güncel ondalık değerden çıkarılamayan ağırlıklı bir konuma bir “0” girin. Örneğin: Ondalık 50’yi ikiliğe çevirmek için. 50 - 32 bit konumu 5 = 1 18 - 16 bit konumu 4 = 1 . 2 - 2 bit konumu 1 = 1 0 Değer bit değerlerine (3,2 ve 0 bitlerine) bir “0” girmek sonuç değerini vermeyi sağlar. Sonuç “110010” Ondalık 50’nin eşiti ikilik değerin gerçekten 110010 olduğunu doğrulama için, 1’in konumlarının ondalık ağırlıklarını toplayın. 32 (bit 5) 16 (bit 4) - 2 (bit 1) 50 1.1.1.Sekiz Bit Bir Byte Eder Apple II Ailesi Commodore 64 ve VIC-20, Radio Shack TRS-80 ve diğer ünlü mikrobilgisayarların mikroişlemcileri 8-bit çevresinde tasarlanırlar. Sekiz-bit mikroişlemciler zaten böyle isimlendirilmiştir. Çünkü bunlar bilgiyi bir anda sekiz bit olarak işlerler. İşleme sekiz bitten daha fazla olduğunda bu mikroişlemciler ek işlemler gerçekleştirmelidir. Bilgisayar terminolojisinde bilginin bit 8-bit birimi “byte” olarak adlandırılır. Sekiz bitle, bir byte 0 (ikilik 00000000) ile 255 (ikilik 11111111) arasında ondalık değerlerle gösterilir. Bir byte işleme biriminin temelidir. Mikrobilgisayarlar belleklerinin tutabildiği byte numaralarının açıklaması içinde tanımlıdır. Mikrobilgisayar üreticileri belleği 1,024 byte’lık blokların içinde inşa ederler. Bu belirli miktar 210 byte yönelimini yansıtır. 3 gösteriminde bilgisayarların ikilik 1.024 değerinin bir standart kısaltması vardır. Bu K harfidir. Bu sayede bir bilgisayar 256*1.024 (ya da 262,144) byte içeren “256K bellek” içerir. 1.1.2.İkilik Sayıları Toplamak İkilik sayıları ondalık sayılarla aynı yolla toplayabilirsiniz: Bir sütundan sonrakine fazlayı taşıyarak. Örneğin ondalık 7 ve 9 değerlerini toplamak için: “onlar” sütunundan üretilmiş doğru sonucu (16) bir “1” taşımalısınız. Benzer bir şekilde, 1 ve 1 ikilik değerini toplamak için, “ikiler” sütunundan üretilmiş doğru değere (10) bir “1” taşımalısınız. Çoklu-bit sayılarını toplamak biraz karmaşık olur. Çünkü siz bir önceki sütundan bir elde sağlamalısınız. Örneğin bu işlem iki elde gerektirir. 1011 + 11 . 1110 En sağdaki sütunun toplanması (1+1) “0” sonucunu üretir ve 1’in bir eldesi ikinci sütunun içinedir. Eldeyle birlikte ikinci sütunun toplanması (“1+1”+1) “1” sonucunu üretir ve bir elde de üçüncü sütunun içinedir. İkilik toplamada genel kurallar bu tabloda gösterilmiştir. Tablo.1.1. İkilik Toplamada Genel Kurallar: Girdiler Sonuçlar Operand #1 Operand #2 Elde Toplam Elde 0 0 0 0 0 0 1 0 1 0 1 0 0 1 0 1 1 0 0 1 0 0 1 1 0 0 1 1 0 1 1 0 1 0 1 1 1 1 1 1 4 1.1.3.İşaretli Sayılar Şimdiye kadar ikilik içindeki “işaretsiz sayıların” nasıl gösterildiğini tartıştık. Daha önce andığımız gibi bir işaretsiz sayının içindeki her bit onun konumunu yansıtan bir ağırlığa sahiptir. En sağdaki (ya da) en az-belirgin bit 1’in ağırlığına sahiptir. Her daha belirgin bit iki kez ağırlığa sahipse bu onun öncelidir. Böylelikle, eğer bir byte’taki her sekiz bit 0’sa byte 0 değerine sahiptir. Eğer hepsi 1 ise, byte 255 değerine sahiptir. Bununla beraber, siz sık sık pozitif ve negatif değerleri işletmek isterseniz. Bu “işaretli sayılar” dadır. Bir byte bir işaretli sayı yalnızca yedi en az-belirgin bit (0-6 arası) veriyi gösterir. En belirgin bit (7) sayının işaretini belirtir. İşaret biti 0 ise sayı pozitif ya da sıfır ve 1 ise sayı negatiftir. Şekil 0-2 işaretli ve işaretsiz byte’ların sırasını gösterir. 7 6 5 4 3 2 1 0 işaretsiz sayı her bit veri gösterir 7 6 5 4 3 2 1 0 0 pozitif işaretli sayı düşük seviyeli bitler veri gösterir işaret biti=0 7 1 6 5 4 3 2 1 0 negatif işaretli sayı ikinin-bileşeni formundaki düşük seviyeli bitler veri gösterir, işaret biti=1 Şekil.1.2. İşaretli ve işaretsiz sayıların gösterimi. 5 İşaretli sayı tutulurken, bir tekil byte 0 (ikilik 00000000) ve +127 (ikilik 01111111) arasında pozitif değerleri gösterebilir. Ve –1 (ikilik 11111111) ve –128 (ikilik 10000000) arasında negatif değerleri gösterir. Not: -1 ikilik olarak 11111111’dir. Bu 10000001’den daha kolay değil midir? (Bu, 1 ve bir eksi işaret bitidir.) Hayır. Bu yanlış yanıtlar üretebilir. Düşünün Örneğin, +1 ve –1 eklerseniz ne olur. Yanıt kesinlikle 0 olmalı. 00000001 + 10000001 10000010 = +1 = -1 = -2 Böylece -1 göstermek için birkaç yol gerekir. +1 eklediğimizde 0 elde ederiz. –1 için 11111111 ile geldiğinde: bu doğru yanıtı üretir. Bunu test etmek için toplamamızı yeniden yapalım... 00000001 = +1 + 11111111 = -1 1 00000000 = 0 Başındaki fazladan 1-bit “elde”dir. Artık bit toplamadan gelir . Basitçe yok sayabiliriz. 1.1.4.İkinin Bileşeni -1’deki gibi tüm negatif işaretli sayılar özel bir formda gösterilmiştir. Bu yapılan toplamalarda doğru yanıtları üretir. Buna “ikinin bileşeni formu” denir. Negatif sayıların ikilik gösterimini bulmak için (bu ikinin bileşen formunu bulmaktır.) basitçe sayının pozitif formunu alın ve her biti tersine çevirin. (--- her 1’i 0’a ve her 0’ı 1’e ---) sonra sonuca 1 ekleyin. Örneğin devamında –32’nin ikinin bileşeni ikilik gösteriminin nasıl hesaplanacağını gösteriyor. 6 00100000 11011111 + 1 11100000 +32 her biti tersine çevir 1 ekle -32, ikinin bileşeni formunda Şüphesiz, ikinin bileşeni dönüşümü negatif sayıları zor çözülür yapar. İyi ki aynı prosedürü bir (ikinin tümlenmişi) negatif sayının pozitif formunu bulmak için verdiğimizde de kullanabiliyoruz. Örneğin: 1101000 değerinin sahip olduğu değeri bulmak için aşağıdaki gibi bir yol izlenir. 00101111 + 1 00110000 her biti ters çevir 1 ekle = 16+32=48 Assembler programları ayıları ondalık formda (işaretli ya da işaretsiz) girmenize isin verir ve kendiliğinden bütün dönüşümleri yapar. Bununla birlikte bu dönüşümleri kendiniz yapabilecekseniz bellekte ya da bir saklayıcının içinde saklanmış bir negatif sayının açıklamasını yapmak isteyebilirsiniz. 1.2.HEXADESİMAL (ONDALIK) SAYILAR: Gerçi, ikilik sayı sitemi, belleğin içine gönderilmiş sayıları göstermek için işe yarar bir yoldur. Yalnız birinin stringi ve sıfırlarla çalışmak çok zordur. Bunlar zaten hataya meyillidir. Çünkü 10110101 gibi bir sayı, kötü tip tanımlamak için aşırı derecede kolaydır. Yıllar önce, programcılar genel olarak bitlerin gruplarıyla işlem yapmanın tek bitlerle işlem yapmaktan daha iyi olduğunu buldular. En başlangıçtaki mikroişlemciler 4-bit aygıtlardı (bir anda dört bit bilgi işlenirdi). Bu nedenle mantıksal alternatif olan ikilik bitleri dördün grupları olarak numaralayan bir sistemdi. Bildiğiniz gibi, dört bit ikilik değerleri 0000 ile 1111 arasında (ondalık 0 ile 15 değerleri arasına eşittir), 16 olası olası kombinasyonun bir toplamı olarak gösterir. Eğer sayma sistemi bu 16 kombinasyonda gösterirse, 16 rakama sahip olmalıdır. Bu da bir “taban 16 sistemi” olmalı… Eğer taban 2 sayılıysa “binary” ve taban 10 sayılıysa “desimal” denir. Peki bir taban 16 sitemi için hangi terim uygundur? Evet herkes taban 16 sistemini bir Yunan sözcüğü olan “hex” (6 için) ile bir Latin sözcüğü olan “decem” (10 için) birleşimiyle oluşan “hexadecimal – 7 (hexadesimal)” ismiyle isimlendirdi. Bu sayede taban 16 sistemine “hexadesimal” (onaltılı) sayı sistemi dendi. Hexadesimal sayı sistemindeki 16 rakamın ilk 10’u 0 ile 9 arasındadır. (ondalık 0 ile 9 arasındaki değerler) ve son altısı A ile F arasında (ondalık 10 ile 15 arası değerler) etiketlendi. Tablo 0-2 her hexadesimal rakamın ikilik ve ondalık değerini listeler. Tablo.1.2. Hexadesimal Sayı Sistemi: Hexadesimal Binary Ondalık Hexadesimal Binary Ondalık Rakam Değeri Değeri Rakam Değeri Değeri 0 0000 0 8 1000 8 1 0001 1 9 1001 9 2 0010 2 A 1010 10 3 0011 3 B 1011 11 4 0100 4 C 1100 12 5 0101 5 D 1101 13 6 0110 6 E 1110 14 7 0111 7 F 1111 15 İkilik rakamlar ve ondalık rakamlar gibi her hexadesimal rakamda kendi tabanının bazı katlarında bir ağırlığa sahiptir. 16 tabanlı hexadesimal sayı sisteminde her rakam ağırlığı bir sağındaki bir sağındaki rakamdan daha büyüktür. Bu 16 defa sürer. En sağdaki rakam bir 160’ın ağırlığındadır. Yanındaki 161 ağırlığında, ve böyle devam eder.Örneğin: Onaltılı 3AF değeri ondalık 943 değerine sahiptir. Çünkü: (3*162) + (A*161) + (F*160) ondalık formda (3*256) + (10*16) + (15*1) = 943 1.2.1.Hexadesimal Sayıları Kullanma BASIC ve diğer yüksek-düzeyli diller genellikle sayıları ondalık formda gösterirken, assembler dili genellikle sayıları hexadesimal formda gösterir. Bu adresleri, talimat kodlarını ve bellek bölgesiyle saklayıcılarının içeriğini kapsar. Böylelikle programınızdan en yüksek verimi almanız için “hexadesimal düşünmeyi deneyin”. Bu ilk başta zordur, ancak bu daha fazla deneyim kazanmanızı kolaylaştırır. 8 1.3.ASCII / BINARY KOD DÖNÜŞÜMLERİ Bilgisayar her zaman klavye karakterlerini ASCII’ye çevirir. Girdi bir “sayı” sunarsa, işlemci onu işletmeden önce binary’ye ya da BCD’ye dönüştürmelisiniz.. Aynı şekilde önce bir sayı yazdırabilir ya da bunu ekran üzerinde gösterebilirsiniz. Bunu ASCII forma sokmanız gerekir. Biz her problemi bu bölümde adresleyeceğiz: ASCII sayıdan binary’ye ve binary sayıdan ASCII’ye nasıl dönüştürülür. (ASCII ve BCD arasındaki dönüşüm benzer prosedür gerektirir. Bu alıştırma okuyucuya bırakılmıştır.) 1.3.1.ASCII Strigleri Binary’ye Dönüştürme: Tablo, 6-8 0 ile 9 arasındaki rakamlar için ASCII kodlarını gösterir. Görebileceğiniz gibi değer aralığı 30H’dan 39H2a kadardır. Zaten ondalık rakamın binary eşiti basitçe ASCII kodun düşük dört biti olduğu not edilmiştir. Tablo.1.3. Ondalık Rakamlar İçin ASCII kodları ASCII Değer (Hex) Ondalık Rakam(Dec) 30 0 31 1 32 2 33 3 34 4 35 5 36 6 37 7 38 8 39 9 Daha önce söylediğimiz gibi ondalık sayılar 10’un kuvvetleriyle çarpılmış rakamları dizisiyle açıklanmıştır. Örneğin: 237 = (7*1) + (3*10) + (2*100) ya da 237 = (7*100) + (3*101) + (2*102) Bir anda bir rakam olarak sayıları girmemizden beri, bir ASCII-tabanlı ondalıktan ikiliğe dönüşüm yordamı ondalık ağırlıkları için hesap yapmalı. Bu yordam bir ya da daha çok 10 ile çarpma işlemi içermeli anlamına gelir. Örneğin: operatör tipleri 93 ise, siz 3 eklemeden önce 9 ile 10’u çarpmalısınız. Genelde, dönüşüm süreci bu düzende işler. 9 Dönüşüm yordamı ilk (en belirgin) rakamı ASCII kodun dört yüksek-düzende biti olarak parçalara ayırarak binary’ye çevirmelidir. Sonra binary değerini kısmi sonuca kaydeder. Yordam birkaç alt dizi rakamlarını binary’ye dönüştürmelidir., bir önceki kısmi sonucu 10’la çarpmalı, sonra yeni rakamı çarpıma (bu yeni bir kısmi sonuç üretir) eklemelidir. 1.4.ASCII’den Binary’ye Dönüşüm Algoritması Siz genellikle negatif sayıları pozitif sayılar kadar iyi dönüştürmeye ihtiyaç duyarsınız. Ve sayılar bir ondalık ayıracı içerir, böylece dönüşüm programınız eksi (-) ve nokra (.) karakterlerini de hesaplamalı. Şekil 6-3 bellek içindeki bir ASCII stringi ikinin bileşeni (işaretli) binary sayıya çeviren bir algoritma için akış diyagramıdır. Sayıların 16-bite sığdığını varsayarız, böylece sayıların limiti –32768 ile +32767 dir. Başlamak için, sonuç ve ondalık sayaç (ondalık ayıracının sağındaki rakamların sayısı) sıfırlanır ve program geçen öndeki blokları tarar. Bu noktadan program sayının negatif ya da pozitif olup olmamasına bakarak iki yoldan birini alır. Bu yollar benzerdir. Dönüştürülmüş negatif negatif sayıların hariç tutulması bir pozitif sayı 32,767’ye karşı denetlenmişken negatif sayı –32,768’e karşı denetlenmiştir. Ve tümlenmiş olmalıdır. Şekil 63A’da güncel dönüşümü yapan CONV_AB adlı prosedürün akış diyagramı verilmiştir. CONV_AB prosedürü sonraki string karakterinin ondalık ayıracı olup olmadığını denetleyerek başlar. Eğer ayıraç varsa, CONV_AB kalan karakter sayısını “ondalık sayaç” olarak kaydeder, sonra string göstergesini ilerletir. Eğer sonraki karakter ondalık ayıracı değilse CONV_AB onun ondalık rakam olup olmadığını denetler. Eğer bu karakter bir rakam değilse CONV_AB bunun geçersiz olduğunu bildirir ve bir hata göstergesi ayarlar. Sonra çağrılan programa geri döner. Geçerli bir rakam karakteri bulma üzerine CONV_AB güncel kısmı sonucu 10’la çarpar. Sonra ASCII karakteri bir rakama çevirir ve sonra bunu sonuca ekler. Eğer toplama elde üretirse, CONV_AB bir hata göstergeci ayarlar ve döner. Başka şekilde bu ayıracı arttırır ve ondalık ayıraç denetleme talimatlarına geri döner. Tüm string dönüştürüldüğünde, CONV_AB çağrılan programa geri döner. 1.4.1.Ascıı’den Bınary’ye Dönüşüm Programı Örnek.1.1. bunu gerçekleştiren bir prosedür ve ondan önce algoritmasını gösteriyor. Bu prosedür (ASCII_BIN) data segment’teki (-belki de bir READ_KEYS prosedürüyle girilmiş Örnek 6-4 -) bir ASCII stringi bir 16-bit işaretli sayıya dönüştürür. ASCII_BIN stringin başlangıç adresini DS:DX’ten, karakter sayacını (en yüksek 7) CX’ten alır. Rastlantısız olarak bunlar READ_KEYS prosedürü parametreleri ASCII_BIN 16-bit değeri AX’in içine döndürür. Rakamların sayısı ondalık ayıracından sonra DX’in içindedir ve DI’nın içindeki ilk dönüştürülemez karakterin adresidir. 10 BAŞLA SONUÇ=0 ONDALIK SAYAÇ = 0 BAŞLANGIÇ BOŞLUKLARINI YOKSAY HAYIR HAYIR POZİTİF VARSAY EKSİ İŞARETİ Mİ (-)? ARTI İŞARETİ Mİ (+)? GÖSTERGEC = GÖSTERGEC + 1 GÖSTERGEC = GÖSTERGEC + 1 CONV_AB (STRING DÖNÜŞTÜR) CONV_AB (STRING DÖNÜŞTÜR) EVET EVET DÖNÜŞÜM HATASI DÖNÜŞÜM HATASI HAYIR HAYIR EVET EVET SONUÇ < -32768? SONUÇ < -32768? HAYIR SONUÇU TÜMLE HAYIR HATA GÖSTERGECİNİ AYARLA BİTİR Şekil.1.3. Bir ASCII stringi binary’ye çeviren algoritma 11 CONV_AB HAYIR ONDALIK AYIRAÇ? EVET ONDALIK SAYACI KAYDET GÖSTERGEÇ = GÖSTERGEÇ + 1 HAYIR KARAKTER BİR RAKAM MI? EVET KISMİ SONUÇU 10’LA ÇARP ASCII KODU BINARY RAKAMA DONUŞTUR SONUÇ = SONUÇ + RAKAM EVET SONUÇ ÇOK MU BÜYÜK? HAYIR GÖSTERGEÇ = GÖSTERGEÇ + 1 HATA GÖSTERGEÇİNİ AYARLA DAHA KARAKTER VAR MI? HAYIR GERİ DÖN Şekil.1.4. Klavyeden bir string okuyan prosedür. 12 TITLE READKEYS – 50 tuş darbesini okur ; Bu prosedür 50 tuşu okur ; Girdi:Yok ; Sonuçlar: DS:DX = String adresi ; CX = Karakter sayacı ; ; Assemble with: MASM READKEYS; ; Link with: LINK callprog+READKEYS; PUBLIC READ_KEYS DSEG SEGMENT PARA PUBLIC ‘DATA’ USER_STRING DB 51,51 DUP(?) DSEG ENDS CSEG SEGMENT PARA PUBLIC ‘CODE’ ASSUME CS:CSEG,DS:DSEG READ_KEYS PROC FAR PUSH AX MOV AX,DSEG ; DS’yi başlangıç durumuna getir MOV DS,AX LEA DX,USER_STRING ; String oku MOV AH,0AH INT 21H SUB CH,CH ; CX’ten karakter sayacını oku MOV CL,USER_STRING+1 ADD DX,2 POP AX RET ; DX noktasını text yap ; AX’i yerine koy ; Ana programa geri dön READ_KEYS ENDP CSEG ENDS END 13 Örnek.1.1..ASCII stringi binary’ye dönüştüren prosedür. TITLE ASC_BIN – ASCII’den binary’ye dönüştürür ; bir ASCII stringi onun 16-bit, ikinin bileşeni ; binary eşitine dönüştürür. ; Girdiler: DS:DX = Stringin başlangıç adresi ; CX = Karakter sayacı ; Sonuçlar: CF = 0 hata olmadığını bildirir ; AX = ikilik değer ; DX = Ondalık ayıracından sonra sayaç ; rakamları ; DI = 0FFH ; CF = 1 hata bildirir DS:DI = dönüştürülemez karakterin adresi ; DX ve CX meyilsiz ; ; Assemble with: MASM ASC_BIN ; Link with: LINK callprog+ASC_BIN PUBLIC ASCII_BIN .286C CSEG SEGMENT PARA ‘CODE’ ASSUME CS:CSEG ASCII_BIN PROC FAR PUSH BX ; BX ve CX’i kaydet PUSH CX MOV BX,DX ; BX’in içine ofseti koy SUB AX,AX ; Başla, sonuç = 0 SUB DX,DX ; ondalık sayaç = 0 MOV DI,00FH ; hatalı karakter olmadığını varsay CMP CX,7 ; String çok uzun mu? JA NO_GOOD ; Öyleyse, CF’yi CF yi ayarlamaya 14 ; git ve çık BLANKS: CMP BYTE_PTR [BX],’’ ; Geçmiş önceki boşlukları ; tara JNE CHK_NEG INC BX LOOP BLANKS CHK_NEG: CMP BYTE PTR [BX],’-’ ; Negatif sayı mi? JNE CHK_POS INC BX ; Öyleyse, göstergeci arttır DEC CX ; sayacı azalt, CALL CONV_AB ; stringi dönüştür JC THRU CMP AX, 32768 ; sayı çok mu küçük? JA NO_GOOD NEG AX JS ; Hayır. Sonucu tamamla GOOD CHK_POS: CMP BYTE_PTR [BX],’+’ ; Pozitif sayı mi? JNE GO_CONV INC BX ; Öyleyse göstergeci arttır DEC CX ; sayacı azalt GO_CONV: CALL CONV_AB ; Stringi dönüştür JC THRU CMP AX,32767 ; sayı çok mu büyük? JA NO_GOOD GOOD: CLC JNC THRU NO_GOOD: STC THRU: ; öyleyse, Elde Bayrağını ayarla POP CX ; register’ları yerine koy POP BX RET ; ve çık ASCII_BIN ENDP ; Bu prosedür asıl dönüşümü gerçekleştirir. 15 CONV_AB PROC PUSH BP ; gelişi güzel register’ları PUSH BX ; kaydeder MOV BP,BX ; BP’nin içine göstergeci koy SUB BX,BX ; ve BX’i temizle CHK_PT: CMP DX,0 JNZ RANGE ; Ondalık ayıracı bulunmuş mu? ; öyleyse, izleyen denetimi atla CMP BYTE PTR DS:[BP],’.’ : Ondalık ayıracı mi? JNE RANGE DEC CX ; öyleyse, sayacı azalt, MOV DX,CX ; ve sayacı DX’in içine kaydet JZ END_CONV ; CX=0’sa çık INC BP RANGE: ; göstergeci arttır CMP BYTE PTR DS:[BP],’0’ ; Karakter bir rakam JB NON_DIG ; değilse... CMP BYTE PTR DS:[BP],’9’ JBE DIGIT NON_DIG: MOV DI,BP STC JC ; adresini DI’nın içine koy ; Elde Bayrağını ayarla END_CONV ; ve çık NON_DIGIT: IMUL AX,10 ; AX’in içindeki rakamı 10’la çarp MOV BL,DS:[BP] ; ASCII kodunu çıkar AND BX,0FH ; yalnızca yüksek bitleri kaydet, ADD AX,BX ; kısmi Sonucu güncelle JC END_CONV ; sonuç çok büyükse çık INC BP ; aksi halde, BP’yi arttır LOOP CHK_PT CLC ; ve devam et ; bittiğinde, Elde Bayrağını temizle END_CONV: POP BX ; register’ları yerine koy POP BP RET ; ana programa geri don CONV_AB ENDP CSEG ENDS END 16 DX’in içindeki değer sonucun büyüklüğünü gösterir. Bu size karışık boyutlarda dönüştürülmüş sayıları işletirseniz hangi “ölçek etkeni”ni uygulayacağınızı söyler. DX’in içeriği 0 (sonuç bir tamsayı) ile 5 (sonuç bir basit kesir) arasında olabilir. Örneğin: AX 1000H (ondalık 4096) içerir ve DX 2 içerirse, sonucunuz ondalık 40,96 değerini gösterir. Bu Sonucu DX’in içinden 3 olarak dönen önceki değer olan sonuca eklemek için, bir önceki Sonucu öncelikle 10’a bölmeniz gerekiyor. Benzer bir şekilde 40.96’yı DX’in içinden 0 olarak dönen bir önceki sonuca eklemek için yeni değeri öncelikle 100’e bölmeniz gerekir. Elde Bayrağı (Carry Flag - CF) dönüşüm sırasında hata meydana gelip gelmediğini gösterir. Eğer CF 0’sa, sonuçlar geçerli, eğer CF 1’se ASCII_BIN aşağıdaki hatalardan birini bulmuştur. String yedi karakterden büyükse (CX>7) AX ve DX 0 tutar ve DI 00FFH tutar. ASCII_BIN geçersiz karakter buldu, DI bunun ofset değerini tutar. Sayı aralığın dışındaysa (-32768’den daha küçük, 32767’den daha büyük) AX sıfırsızdır ve DI 00FFH’ı tutar. Yanıtın geçerliliğini denetlemek için ASCII_BIN’i bu yazımda çağırın... CALL ASCII_BIN ; Dönüşüm prosedürünü çağır JNC VALID OR DI,DI ; yanıt geçerli mi? ; hayır. Hata durumu bulundu JNZ INV_CHAR OR AX,AX JNZ RANGE_ER .. ; string çok büyüktü .. RANGE_ER: .. ; sayı aralık dışında .. INV_CHAR: .. ; geçersiz karakter .. VALID: .. : yanıt geçerli .. 17 1.4.2.Binary Sayıları Stringe Çevirmek Bir sonuç yazdırmak ya da bunu ekranda göstermek için, onu ASCII’ye çevirmeniz gerekir. İyi ki, bunu yapmak kolay. Bir 16-bit binary sayıyı ASCII’ye dönüştürmek için sayının içerdiği 1, 10, 100 ,1000, 10000’leri bildiren ve bu sayaçların her birini bir ASCII karaktere dönüştüren bir programa ihtiyacınız var. ASCII karakterleri hesaplandığı gibi çıktı verebilir ya da onları bellekte bir string olarak saklayabilir ve başka bir programla daha sonra çıktı olarak verebilirsiniz. Örnek 6.6 AX içindeki bir 16 bit binary sayıyı bellekte bir ASCII stringe çeviren BIN_ASCII adında bir prosedürdür. Çeşitli sayaçlar türetmek için, BIN_ASCII AX’in içeriğini ardı sıra 10’a böler ve her bölme işleminin kalanını string inşa etmek için kullanır. BIN_ASCII dönüştürülmüş stringlerin adresini DS:DX2in içine ve karakter sayacını CX’in içine geri döndürür. Örnek.1.2. Binary sayıyı stringe çevirme TITLE BIN_ASC – Binary’yi ASCII’ye çevirme ; Data segmentteki Işaretli binary sayıyı altı-byte’li ASCII ; stringe (artı işaretli dört rakam) çevirir. ; Girdiler: AX = Dönüştürülmüş sayı ; DS:DX = string tamponunun başlangıç adresi ; Sonuçlar: DS:DX = stringin başlangıç adresi CX = Karakter sayacı ; Diğer register’lar saklı. ; Assemble with: MASM BIN_ASC; ; Link with: LINK callprog+BIN_ASC; PUBLIC BIN_ASCII CSEG SEGMENT PARA PUBLIC ‘CODE’ ASSUME CS:CSEG BIN_ASCII PROC FAR PUSH DX ; ana programın register’larini sakla PUSH BX PUSH SI 18 PUSH AX MOV BX,DX ; ofseti BX’in içine koy MOV CX,6 ; tamponu boşluklarla doldur FILL_BUFF: MOV BYTE PTR [BX],’’ INC BX LOOP FILL_BUFF MOV SI,10 OR ; hazırla -*- 10’a bol AX,AX ; i değeri negatifse, JNS CLR_DVD NEG AX ; sayıyı pozitif yap CLR_DVD: SUB DX,DX ; bölümün üst yarısını temizle DIV SI ; AX’i 10’a böl ADD DX,’0’ DEC BX ; kalanı ASCII rakamına dönüştür ; buffer yardımıyla yedekle MOV [BX],DL INC CX OR ; dönüştürülen karakterleri say AX,AX ; hepsi bitti mi? JNZ CLR_DVD POP AX OR ; karakteri stringin içine sakla ; değilse, yeni rakamı al ; evet, asıl değeri al AX,AX ; negatif miydi? JNS NO_MORE DEC BX ; evet. İşaretini sakla MOV BYTE PTR [BX],’-’ INC CX ; ve karakter sayacını arttır NO_MORE: POP SI ; register’ları yerine koy POP BX POP DX RET ; ve çık BIN_ASCII ENDP CSEG ENDS END 19 2.BÖLÜM 2.ADRESLEME MODLARI 2.1.8086/8088 Hafıza Mimarisi 2.1.1.Lojik ve Fiziksel Hafızalar 8086/8088 mikroişlemcisi 20-bit Adres Yolu ile toplam 1048576 (1M) byte hafıza hücresi adresleyebilmeye karşın, her iki işlemcinin fiziksel hafıza yapıları farklıdır. Bununla beraber bu işlemcilerin lojik hafızaları Şekil 4.13’te görüldüğü gibi aynıdır. Lojik hafıza, yazılım tarafından programcıya görülen hafızaya verilen isimdir. Bu hafıza, donanım tasarımcısı tarafından görülen, gerçek hafıza yapısını oluşturan fiziksel hafızadan farklı olabilir. 8088 ve 8086 mikroişlemcilerin lojik hafızası 0000h’tan başlayıp FFFFh’a kadar uzanır. Lojik hafıza genişliği bir byte (8-bit) olup bu adreslerin uzunluğu 1M byte hafıza bloğu belirtir. Mikroişlemci tarafından adreslenen 16-bit hafıza kelimesi, her herhangi bir byte adresinden başlar ve peş peşe 2 byte işgal eder. FFFFFh 1M byte 00000h Şekil 2.1. 8086/8088 lojik hafıza haritası. 8088 ve 8086 fiziksel haritaları genişlik olarak birbirinden farklıdır. 8088 hafızası 8-bit, 8086 hafızası ise 16-bit genişliğindedir. Programcı için hafıza her zaman 8-bit genişliğinde olmasına rağmen, fark sadece tasarımcısı için bulunur. 20 Şekil 4.14.8088 mikroişlemcisinin hafıza alanını göstermektedir. Bu hafıza haritası Şekil 4.13’te verilen lojik hafıza haritası ile aynıdır. 8088’in hafıza arabirimi 8085A işlemecisine benzemektedir. FFFFFh 00000h Şekil 3-2. 8088 fiziksel hafıza haritası. 8086 mikroişlemcisinin fiziksel hafıza haritası Şekil 4.15’te görülmektedir. 8088’den farklı olarak iki ayrı hafıza bloğu içermektedir. Tek blok (yüksek hafıza) ve çift blok (düşük hafıza). Her 8086 bloğu 512K*8 olup toplam adreslenebilir, 8086, byte veya kelime (16-bit, Word) verisini doğrudan adresleyebilmektedir. Bundan dolayı, 8086, 16 bit bir kelimeyi bir işlemde okuyup yazabilmektedir (verinin adresinin çift olması sağlandığında). Buna karşın, 8088, 16-bit veri aktarımı için 2 okuma veya yazmaya gerek duyar. 8086 yazılımı daha hızlı çalışır. Çünkü, 8086 bir çok komutu ve 16-bit veriye 8086’in iki katı hızında erişir. Tek Blok Çift Blok FFFFFh FFFFEh 512 K 512 K byte byte 00005h ---------------- ---------------- 00004h 00003h 00002h 00001h 00000h Yüksek Hafıza Düşük Hafıza Şekil 3-3. 8086 fiziksel (donanım) hafıza haritası 2.1.2. Segment’li Hafıza Yapısı 8086/8088 mikroişlemcilerinde hafızaya erişim segment saklayıcıları yoluyla yapılır. Her bir segment bloğu 64K byte’tır. Şekil 4.16’da segment saklayıcıları ile adreslenen bir hafıza 21 haritası örneği görülmektedir. Hafıza alanının aynı anda 4 farklı segment bulunabilmektedir. Bunlar kod segment (CS), veri segment (DS), ekstra segment (ES), ve yığın segment (SS). AFFFFh SS Yığın A000 Segment A0000h ES 8FFFFh Ekstra 8000 Segment 80000h DS 3FFFFh Veri 3000 Segment 30000h 1FFFFh CS Kod 1000 Segment 10000h Şekil.2.4. Segment saklayıcıları ile adreslenen bir hafıza haritası Her segment saklayıcısı, 20-bit adresin 16-bit kısmını tutar. Segment saklayıcıda bulunan 16-bit adresin düşük değerli bölümüne, 0h (0000h) eklenir. Ayrıca bir ofset (indis) bu adresle toplanarak, donanım tarafından otomatik olarak, 20-bit adres elde edilir. Bu işleme lojik adresin fiziksel adrese çevrilmesi denir. Segment saklayıcılarına göre, aşağıda açıklanacağı gibi, ofset, değişik saklayıcılardan gelir. Eğer bir 8086/8088 sistemi sadece 64K byte hafıza içeriyorsa, bütün 4 segment saklayıcısı 0000h ile yüklenir ve segment’ler üst üste çakışır. Bu durumda adres aralığı X0000h – XFFFFh arasında değişir. (X herhangi bir 16-lı rakamdır.) Her bir segment saklayıcısı, özel bir fonksiyona sahiptir ve bir veya daha çok indis veya işaretçi saklayıcısı ile ilişkilidir. Bir hafıza adresi üretmek için, bir segment saklayıcısının içeriği, bir ofset adres tutan bir indis veya işaretçi saklayıcısına eklenir. 22 Şekil 4.17’de bir komut tarafından adreslenen bir verinin, fiziksel adresinin üretimi görülmektedir. Bu örnekte, veri segment saklayıcısı DS 1000h içermekte, yeni veri segment 10000h fiziksel adresinden itibaren başlamaktadır. Taban saklayıcısı BX’te ofset adres 0020h bulunmakta, ve böylece fiziksel adres 10020h veya 1000h*10h+0020h olmaktadır. BX 10020h 0020 | | | | | | | | | | ofset 10003h 10002h DS 10001h 10000h 1000 Şekil .2.5. Veri segment’inde bulunana bir hafıza hücresine erişim Kod segment CS, program ve veri alanı olarak kullanılabilmesine rağmen genelde kodlarının bulunduğu alandır. 8086/8088 tarafından yürütülecek bir sonraki komutun adresi, komut işaretçisi IP’ye CS * 10h içeriğinin toplanmasıyla elde edilir. Veri segment’i DS, bir çok komut ve adresleme modu tarafından erişilen program verilerini tutar. Hafızadaki verinin adresi, BX,SI veya DI saklayıcılarından birine DS * 10h içeriğinin toplanmasıyla elde edilir. Yığın (stack) segment’i SS, LIFO (Last In First Out) tarzında çalışmaktadır. Bir yığın hücresinin adresi, SP’nin içeriği artı SS *10h’tır. BP tarafından adreslenen veri de normal yığın segment’inde bulunur. 23 ES string komutlarından kullanılan veri alanıdır. Bir string komutu yürütüldüğünde, hedef adres DI ES * 10h, kaynak veri adresi ise, SI artı ES * 10’tır. Aşağıda Tablo 4.5’te 8086/8088 mikroişlemcisinin değişik işlemleri ve bunlarda otomatik olarak kullanılan saklayıcılar görülmektedir. Tablo 3.1. İşlemlere göre değişik segment adres kaynakları. İşlem Çeşidi Segment Alternatif Segment Ofset Komut okuma CS yok IP Yığın işlemi SS yok SP Veri İşlemi (aşağıdakiler hariç) DS CS,ES veya SS çeşitli String kaynak DS CS,ES veya SS SI String hedef ES yok DI BP taban saklayıcı olarak kullanıldığında SS CS,ES veya SS çeşitli 2.1.2.1. Segment’li Hafıza Yapısının Avantajları Yukarıda anlatılan segment’li hafıza yapısı, ilk bakışta şaşırtıcı ve zor görülebilir. Bu hafıza yapısı için hatırlanması gerekenler özetle şunlarlar. Program işlem kodları CS alanından okunmakta, program verileri DS ve ES alanlarında saklanmaktadır. Yığın işlemleri ise, SP ve BP saklayıcılarını kullanarak SS üzerinde işlem yapar. Ayrı kod ve veri alanlarının olmasının ilk avantajı, bir programın, farklı veri blokları üzerinde çalışabilmesidir. Bu işlem, DS saklayıcısına farklı bir bloğa işaret eden yeni bir adresin yüklenmesiyle yapılır. Segment’li hafıza yapısının en büyük avantajı, lojik adresler üreten x86 programlarının hafızanın herhangi bir yerine yüklenip çalıştırabilmesidir. Bunun nedeni, lojik adreslerin, her zaman, CS taban adresinden bağımsız olarak, 0000h ile FFFFh arasında değişmesidir. Çok-görevli (multi-tasking) x86 tabanlı bir ortamı veya Windows 95/98/NT işletim sistemini düşünelim. Bir çalışan aktif programın geçici olarak sabit diskte saklandığını ve onun yerine, yeni bir programın getirildiğini farz edelim. Bu çeşit programla, hafızanın herhangi bir yerinde çalışacakları için, tekrar yerleştirilebilir (relocatable) olarak adlandırılır. Programların bu şekilde çalışabilmesi, segment saklayıcıları yoluyla olmaktadır. Segment saklayıcılarının yani program, veri ve yığın saklayıcılarının taban adresinin değiştirilmesiyle programlar hafızanın herhangi bir yerinde çalışabilmektedir. 24 8085A ve benzeri birçok 8-bit mikroişlemci ve mikro denetleyicide, bu şekilde bir hafıza adres üretimi olmadığı için, programların tekrar yerleştirilebilirliği mümkün değildir. Yani, bir 8085A işlemcisi için, program ve verilerin başlangıç adresleri, ORG (Origin) gibi assembler ifadeleri ile belirlenip kod üretimi yapıldıktan sonra, bu adreslere, program ve veriler yüklenmelidir. Bu şekilde, program ve veriler, bir bakıma, hafızaya kök salar ve başka yere taşınamaz. Program ve verileri başka bir adrese yükleyebilmek için, ORG ifadesindeki adresler değiştirilir, sonra tekrar derleme yapılır ve yeni ikili kod üretilir. Bu sayede yeni adres yerleşimi için kod elde edilir. 2.2. Adresleme Modları 80286 (Kısa 286) işletmek üzere sizin programınızın operand’larını oluşturmak için yolların çeşitliğini destekler. 286 bunları bir tutucudan oluşturabilir., kendisi bir direktifle, ya da bellek konumundan ya da bir I/O kapısından. Hepsi için adresleme kiplerini 7 gruba ayırabilirsiniz. 1) Saklayıcı adresleme 2) Kesin adresleme 3) Doğrudan adresleme 4) Saklayıcı dolaylı adresleme 5) Tabana dayalı adresleme 6) Doğrudan dizilmiş adresleme 7)Taban dizili adresleme Mikroişlemci direktifin içindeki bir “mod alanı” ‘nın içeriğini sınayarak. Bu yedi adresleme modunu kullanmak için belirtir. Assembler mod alanını kaynak programdaki operandlarının görünüşlerinin tabanında ayarlar. Örnek olarak bunu girerseniz. MOV AX, BX Assembler her iki operandı (AX ve BX) saklayıcı adresleme modu için kodlar. Bununla beraber, eğer kaynak operandın başına ve sonuna köşeli parantez koyarsanız ve girerseniz. MOV AX, [BX] Assembler kaynak operandını (BX) saklayıcı dolaylı adresleme modu için kodlar. 25 Tablo 3-1 asembler formatını gösterir ve 286’nın 7 operand adresleme kipi için hangi segment tutucusu fiziksel adresini hesaplamak için kullanıldı. Not: Bütün kipler data segmentin içindeki verinin bu durumda yığın segmentin varsaydığı başvurmayı üstlenir. (DS segment saklayıcısıdır). BP saklayıcısının kapsadığını hariç tutar. (SS segment saklayıcısıdır.) Not: 286’nın string direktifleri DI noktalarının ekstra segmentteki yerleşimi data segmentdekinden daha iyidir. Tablo 2.1. 80286 Adresleme Modları: Adresleme Modu Operand Biçimi Segment Tutucu Tutucu reg Yok En yakın data Yok Doğrudan disp DS label DS [BX] DS [BP] SS [DI] DS [SI] DS [BX]+disp DS [BP]+disp SS [DI]+disp DS [SI]+disp DS [BX][SI]+disp DS [BX][DI]+disp DS Dolaylı saklayıcı Göreceli taban Doğrudan dizilmiş Taban dizilmiş 26 [BP][SI]+disp SS [BP][DI]+disp SS Notlar:1) “disp” taban izilmiş adresleme için seçimliktir. 2) “reg” her 8 veya 16-bit saklayıcı olabilir., IP hariç 3) “data” bir 8 veya 16-bit sabit değerinde olabilir. 4) “disp” bir 8 veya 16-bit işaretlenmiş ayırma değerinde olabilir. ES segment saklayıcısı gibi kullanıldı. Bütün diğer talimatlar Tablo 3-1’de atanmış olarak gösterildi. Bu bölümün devamında, her zaman tanımladığımız bir adresleme kipini, bir örnekte kullanımını sergileyeceğiz. Genellikle, biz 286’larda MOV (Move) talimatını bunu sergilemek için kullanırız. 2.2.1.Saklayıcı ve Kesin Adresleme Tutucu adreslemede, 286 operandı tutucudan (ya da içine yüklenenden) gidip getir. (Swap) Örneğin: MOV AX, CX 16-bit içerikli sayaç tutucusunu (CX), akümülatör tutucusuna (AX) taşır. CX saklayıcısının içeriğini değiştirmez. Burada, 286 adresleme saklayıcısını kaynak operandı CX’den almak ve AX hedef saklayıcısının içine yükler. “Kesin adresleme” size 8 veya 16-bit sabit değeri kaynak operand gibi belirtmenize izin verir. Bu sabit talimat içindedir. (assembler’ın koymuş olduğu) ve tutucu ya da bellek erişiminden daha iyidir. Örneğin: MOV CX, 500 Ondalık değer olan 500’ü CX tutucusuna yükler ve MOV CL, -30 -30 değerini CL tutucusuna yükler. 27 Yakın operand zaten EQU direktifiyle tanımlanmış bir simge olabilir.Bunun gibi bir form geçerlidir. K EQU 1024 --------MOV CX,K Sorunlardan sakınmak için, 8 bit 127 (7FH)’tan 128 (80H)’a kadar ve 16-bit 32767 (7FFFH)’tan 32768 (8000H)’a kadar. İşaretli numaralandırır. Eğer bunlar işaretsizse en yüksek 8 ve 16 bit değerler.sırasıyla 255 (0FFH) ve 65535 (0FFFFH)’tır. Kesin Değerler İşaretli Uzatılmıştır: Assembler her zaman hedefin içindeki kesin değerleri “işaretli uzatır”. Bu bütün hedefin 8 veya 16 bitlerine kaynağın en belirgin bit’ini kopyalar. Örneğin: MOV CX, 500 ; girerseniz assember kaynak değerini (ondalık 500) 10-bit ikilik modelde 0111110100 gibi görür. Bu değer 16-bit hedef saklayıcıya yüklendiğinde (CX), bu modeli “işaretli” bit değerlerinin (0) sekiz kopyasını başa getirerek uzatır. Böylelikle CX, sonunda 0000000111110100 ikilik değerini içerir. İkinci örnekte; 286: 8 bit ikilik modelini –30 (11100010) için CL’nin içine yüklüyor. Bellek Adresleme Modları: Erişim Belleği 286’nın Yürütme Birimi (Execution Unit (EU)) ve Yol birimi (Bus Un it (BU)) tarafından ek bir çaba gerektirir. EU biriminin bir bellek operandı okuması ya da yazması gerektiğinde EU ofset değerini BU’ya verir. BU, bu ofseti bir 20-bit fiziksel adres üretmek için ( dört “0” ekleyerek) segment tutucusunun içeriğine ekler, sonra bu adresi operanda erişmek için kullanır. Efektif Adres: Ofset Yürütme Biriminin hesapladığı, bellek operandı için çağrılan, efektif adrestir (EA). EA segmentin başlangıcından operandın yerine kadar olan byte’ların uzaklığıdır. 16-bit işaretsiz değerin oluşu, EA segmentin içinde nerede yanlış olduğuna başvurabilir. Bu 65,535 (64K) byte üzerinde segmentin başlangıcını geçmiştir. 28 Zamanın miktarı Yürütme Birimi hesaplamak için aldığı EA talimatını yürütmek için almasında uzunluğun belirlenmesi ilk etkendir. Kullandığınız adresleme kipine bağlı olması, EA’nın bazı şeyleri gerektirebilmesi biraz basitçe talimatın içinden bir ayrıma gidip getirmesiyle (swap) oluşmakta. Sonra tekrar; ayırma ekleme, taban tutucusu ve bir dizin tutucu gibi bazı çok uzun hesaplamalar gerektirebilir. Yürütme Zamanına aldırmamak programınızda kritik bir durumdur. Adresleme mov tanımından sonra, BU, bu zaman etkenlerini takdir etmelisiniz. 2.2.2.Doğrudan Adresleme Doğrudan adreslemede, EA kesin veri değerlerinin direktiflerde bulunduğu, direktiflerin içinde bulunur. 286 operand’ın fiziksel adresini üretmek için EA’yı (değişmiş) Data Segment saklayıcısına ekler. Doğrudan adresleme operandı genellikle etikettir. Örneğin direktif: MOV AX, TABLE şeklindeyse TABLE bellek bölgesinin içeriğini AX tutucusuna yükler. Şekil 3-1 talimatın nasıl çalıştığını gösteriyor. DATA SEGMENT MOV AX,TABLE 0000 BB 0001 AX AABB TABLE AA 0002 TABLE + 2 0003 0004 Şekil.2.6. Sayfa 108 Doğrudan Adresleme 29 Not: 286 veriyi siz hariç tutmak isterseniz zıt düzen içinde bellekte depolar. Bu düşük düzen byte’ından sonra yüksek-düzen byte’ını koyar. Verinin yüksek (en belirgin) parçası, en yüksek bellek adresinin içindedir. 2.2.3.Saklayıcı Dolaylı Adresleme Saklayıcı Dolaylı adreslemeyle, operandın etkin adresi ya Bx saklayıcı tabanı, ya BP taban işaretçisi (ya da bir dizin tutucusu (SI ya da DI)) içindedir. Dolaylı saklayıcı operandını saklayıcı operandından ayırmak için köşeli parantezle kapatmalısınız. Örneğin: MOV AX, [BX] bu talimat BX’ le adreslenmiş bellek bölgesinin içeriğini AX saklayıcısının içine yükler. Şekil 3-2 bu örneği resimliyor. BX’in içine bellek adresine OFFSET öneki girebilmek için bir ofset koymanın bir yolu vardır. Örneğin: AX içinde TABLE bölgesinde bir sözcük yüklemek için, bu diziyi kullanın. MOV BX, OFFSET TABLE MOV AX, [BX] Bu iki talimatla aynı işi yapmak için MOV AX, TABLE BX’in önceki önceki içeriğini yok etmesi hariç tutulur. Eğer bir yalnız bellek bölgesine (burada TABLE’ın içeriği) erişmek istiyorsanız bu tek talimat daha duyarlı yaklaşım gösterir. Bununla birlikte, bazı taban adresleriyle başlayan, birkaç bölgeye ulaşmak için saklayıcının içinde etkin adres bulunması daha iyidir. Neden böyle? Çünkü her zaman tutucunun içeriklerini getir-götür adressiz üretebilirsiniz. 2.2.4.Göreceli Taban Adresleme Göreceli taban adreslemeyle assembler etkin adresini BX yada BP tutucusuna bir ayırma değeri ekleyerek hesaplar. BX formu belleğin farklı bölümünde yerleşmiş veri yapısına erişmenin uygun yolunu verir. Bunu yapmak için, yapının taban adresini saklayıcı tabanının içine koyun tabanda ayrılması ile yapının öğelerine başvurun. Bundan sonra, taban saklayıcıda basit değişiklikler yaparak, yapının içinde değişik kayıtlara ulaşabilirsiniz. Örneğin: Diskten bazı personel kayıtlarını okuduğunuzu varsayın, bulunan her kayıt işçinin kimlik numarasını, bölüm numarasını, bölge numarasını, yaşını, maaşını vb içerir. Eğer böyle numarası kaydın 5. ve 6. byte’larında saklıysa, kaydın adresi BX’le başlıyorsa, direktif böyledir. MOV AX, [BX] + 4 30 DATA SEGMENT MOV AX,[BX] BX 0001 0000 0001 BB TABLE AA 0002 AX AABB TABLE + 2 0003 0004 Şekil .2.7. Dolaylı Register Adresleme DATA SEGMENT MOV AX,[BX] + 4 + BX 001A 0019 EMP_50 001A 001B AX AABB 001C 001D BB 001E AA 001F 0020 Şekil.2.8. Göreceli Taban Adresleme 31 Bu talimat işçinin bölge numarasını AX’in içine yükler. (Ayırmada 4 değeri 5’ten daha iyidir, çünkü ilk byte “0” ’dır) Şekil 3-3 bu örneği sergiler. Macro Assembler göreceli taban operandı belirlemede üç değişik yola izin verir. Eşdeğer 3 direktif: MOV AX, [BP]+4 ; Bu standart formdur, fakat kullanabilirsiniz. MOV AX, 4[BP] ; ilk ayırmayı koyar MOV AX, [BP+4] ; ya da köşeli parantezle birlikte 2.2.5.Doğrudan Dizli Adresleme Doğrudan dizili adreslemeyle, etkin adres ayırma ve dizin saklayıcısının toplamıdır, DI ya da SI’dan biri. Bu adresleme tipi bir tablonun içindeki öğelere erişim için uygundur. Ayırma noktaları tablonun başlangıcına ve dizin saklayıcı noktaları öğenin içinedir. Örneğin : B_TABLE isminde bir byte tablomuz var. Direktif dizisi şöyledir. MOV DI, 2 MOV AL, B_TABLE [DI] Direktif AL saklayıcısının içine 3. öğeyi yükler. 32 DATA SEGMENT MOV AX,TABLE[DI] TABLE 0001 DI 0004 + TABLE + 2 AX AABB BB 0005 TABLE + 4 AA 0006 Şekil.2.8. Doğrudan Dizili Adresleme Bir sözcük tablosu içinde, öğeler bağımsız 2 byte’tır. Böylece dizin değeri olarak çift öğe numaranız olur. TABLE isimli Word tablosuyla talimat dizisi şöyledir. MOV DI, 4 MOV AX, TABLE [DI] Bu direktif dizisi üçüncü öğeyi AX saklayıcısının içine yükler. Şekil 3-4 bu örneği sergiler. 2.2.6.Taban Dizili Adresleme Taban dizili adreslemede, EA bir taban saklayıcı, bir index saklayıcı ve (seçimlik olarak) ayırmanın toplamıdır. Çünkü iki ayrı ofset kabul eder. Bu mod iki boyutlu dizilere erişimde yararlıdır. Burada ayırma ve dizin saklayıcısı sıra ve sütun ofsetini sağlarken taban saklayıcı dizinin başlangıç adresini tutar. 33 Örneğin: bir kimyasal işlem fabrikasında bilgisayarınızın monitöründe altı basınç sübabı var varsayalım. Bu her yarım saatte sübab ayarını okur ve bunları belleğe kaydeder. Birinci hafta içinde bu okuma formu her alt öğe için 336 bloktur. (7 günde her gün için 48 okuma). 2.016 veri değeri toplamıdır. Eğer dizinin başlangıç adresi BX ise, blok ayırması (okuma numarası zamanları 12) DI’nın içindedir; ve sübab numarası ayrımı VALUE değişkeni ile tanımlanmıştır. Bu direktifi kullanabiliriz. MOV AX, VALUE [BX] [DI] Bu direktif bazı seçilmiş basınç sübaplarını AX içinden okur. Şekil 3-5’te bu talimat data segmentin 100h ofset adresine sahip bir diziden subab-4 (2.okuma)’ün üç okumasını özetler. Burada taban dizili adresleme operandları için bazı diğer geçerli biçimleri verilmiştir. MOV AX, [BX+2+DI] ; bütün üç terimi bir köşeli paranteze koyabilirsiniz. MOV AX, [DI+BX+2] ; herhangi düzende MOV AX, [BX+2] [DI] ; ya da ayırmayı birleştirebilirsiniz MOV AX, [BX] [DI+2] ; başka saklayıcıya 34 100 MOV AX,VALVE[BX][DI] OKUMA 0 BX 0100 + OKUMA 1 118 DI (VALVE 0) 0018 (VALVE 1) (VALVE 2) VALVE = 8 (VALVE 3) 120 AX BB AA AABB (VALVE 5) Şekil.2.9. Bir iki boyutlu diziden veri değerini çıkarır. 35 OKUMA 2 3.BÖLÜM 3. ASSEMBLER-DİLİ YAPISI 3.1.Giriş: Her assembler dili yapısı bir kaynak program içinde birbirini izleyen [label:](etiket),Mnemonic,[Operand],[;comment] (yorum) isimli 4 alandan oluşur. Bunların içinde yalnızca mnemonic alanı daima gereklidir. Etiket ve yorum alanları daima seçimliktir. Operand alanı operand gereken yapılarda uygulanır. Aksi halde atlamalısınız. (Biz etiket, operand ve yorum alanlarının seçimlik olarak belirtmeniz için boşluklarla göstereceğiz.) Bu alanları çizgi üzerinde herhangi bir yerde girebilirsiniz. Ancak en az bir boşluk (ya da tab) ile ayırmalısınız. Bir assembler-dili yapısında bütün dört alan böyle kullanılır. GETCOUNT: MOV CX, DI ; sayacı başlatır 3.2.Etiket Alanı: Etiket alanı assembler-dili yapısında bir isimle var olur. Bu yapı program içindeki diğer yapılarak kaynak teşkil eder. Böylece etiketler assembler-dili programı içinde aynı amaçlı ve çizgi numarası belirli temel programlara sunumu gerçekleştirir. Bir etiket yapısı en fazla 31 karakterden uzunluğunda olabilir ve iki nokta ile sonlanmalıdır. Böyle oluşabilir: • A’dan Z’ye harfler (veya a’dan z’ye, assembler’de küçük harf büyük harf ayrımı yoktur) • 0’dan 9’arasında sayısal değerler. • Özel karakterler : ? . @ _ $ Herhangi bir karakterle etikete başlayabilirsiniz. Ancak siz bir periyod kullandıysanız (.) ilk karakteri olmalı. AH, AL, AX, BH, BL, BP, CH, CL, CX, CS, DH, DL, DX, DI, DS, ES, SI, SP ve ST saklayıcı isimleridir. Bunları kullanamazsınız. Etiket içinde boşluk kullanamazsınız. Fakat aynı etiketi alt çizgi karakteri ile (_) sağlayabilirsiniz. Örneğin; önceki örnek yapı gibi yazabilirsiniz. GET_COUNT : MOV CX, DI ; sayacı başlatır. Açıkça, GET_COUNT, GETCOUNT’ta olabilir. 36 3.2.1.Etiket İsmi Seçme: Çünkü assembler harflerin, basamakların, simgelerin değişken durumlarını girmenize izin verir. Hemen hemen bütün etiketler kabul edilebilir olarak düşünebilirsiniz. Zaten biz etiket seçme için yorumlar öneriyoruz. • Kısa ve olası isim yapma, mantıklı olabilmeli. Böylece, MPH – MILES_PER_HOUR için tercih edilebilir. CUR_YR, CURRENT_YEAR için mantıklı bir kısaltmalıdır. • Hatasız tipte isim yapma. Her zamanki tipleme sorunu birkaç özdeş harfin bir sırada (HHHH gibi) ve benzer karakterin ( O harfi ile “0” sıfır, I harfiyle 1 sayısı, S harfi ile 5 sayısı gibi ) Burada tanımlama hatası çağırmasının hiçbir mantığı yoktur, hepimiz için bunları başka yolla yapmak yeterlidir. • Etiketleri karıştırabileceğiniz diğerleri ile birlikte kullanmayın. Örneğin, bunun gibi şeyleri kullanmaktan kaçının XXXX ve XXYX 3.3.Mnemonic Alanı: Mnemonic alan (mnemonic ‘in başı “m” harfi sessiz ) 2’den 7’ye kadarki harfler yapı için kısaltmadır. Örneğin: MOV move yapısı için kısaltmadır. ADD add yapısı için kısaltmadır. Assembler her sayısal eşitliklerin içindeki mnemonic yapıyı çevirirken içsel tablolar kullanır. Mnemonic’e ek, bazı yapılar gerektiriyor ki bir ya da iki operand tanımlanması (Örneğin : bir ADD yapısı eklemek için iki terim bilmek gerektiriyor.) Mnemonic assembler’a kaç tane operand, hangi tip, operand alanında ele geçirmeyi söyler. 3.4.Operand Alanı: Operand alanı 80286’ya işlenen veriyi nerede bulabileceğini söyler. Bu bazı yapılar için gereklidir ve diğerleriyle engellenmiştir. Eğer hazırsa, operand alanı 8 tane 1 veya 2 operand içerir. Mnemonic’ten en az bir boşluk ya da tablo ayırmıştır. Eğer iki operand gerekliyse, aralarına bir virgül koymalısınız. İki operandlı yapılarda, ilki hedef operand ve ikincisi kaynak operandtır. Kaynak operand mikroişlemcinin hedef operandın içine ekleyeceği, çıkartacağı, karşılaştıracağı veya depolayacağı değeri belirtir. Örneğin : Bu move talimatında MOV CX, DX CX, DX deki : Kaynak operantının içindeki Dx register’ının içeriğini hedef operandının içindeki CX register’ına taşır. Belki de tahmin ediyorsunuzdur. Hedef operand hemen hemen her zaman değiştirilirken; kaynak operand asla işlemle değiştirilmedi. 37 3.5.Yorum Alanı: BASIC’teki REM’e benzer bir ifade, kaynak programın içinde seçimlik tanımlama ifadesidir; programı daha kolay anlaşılır yapar. Yorumdan önce noktalı virgül (;) gelmelidir. Bu alandan önce en az bir boşluk ya da tabla ayırmak iyi fikir, ancak bunu yapamazsınız. Assembler yorumları yok sayar., ancak programı listeleyeceğiniz zaman yazar. Yorum alanına istediğiniz herhangi bir şeyi yazabilirsiniz., ama yararlı alabilecek, programda ne olduğunu açıklayan yorumlar yapmalısınız. talimatı yeniden vermeyin Örneğin: 1) MOV CX, 0 ; sayaç tutucusunu temizler 2) MOV CX, 0 ; CX’in içine 0’ı taşır. 1. açıklama ikinci açıklamadan daha anlamlıdır. 3.5.1.Yalnız Yorumlar: Tanım bloğu içinde talimatın kendisi tarafından bir yorum tanımlayabilirsiniz. Bunu yapmak için çizginin başına bir noktalı virgül girin; assembler yorum çizgisini tanımlayacaktır ve isleyen her şeyi yok sayar. 38 4.BÖLÜM 4.ASSEMBLER KOMUTLARI 4.1.Veri Transfer Komutları: 4.1.1.Adres Yükleme Komutları: Bu komutlar, bir saklayıcıya veya bir saklayıcı ile bir segment saklayıcısına bir adres yüklemede kullanılmaktadır. Tablo.4.1.de komutların 3 değişik şeklini göstermektedir. 4.1.1.1. LEA (Load Effective Address): LEA komutu, bir saklayıcıya operand ile belirtilen adresi yükler. Tablo.4.1’de birinci örnekte, AX saklayıcısı, operand SUBADR içeriği ile değil (yani bu adresteki veri ile değil) SUBADR adresiyle yüklenmektedir. Tablo.4.1.Adres yükleme komutlarının değişik kullanımları Asembly Dili Yapılan İşlem LEA AX,SUBADR AX SUBADR adresiyle yüklenir LDS DI,LIST DI ve DS LIST’teki adres ile yüklenir LES BX,VEC1 BX ve ES VEC1’deki adres ile yüklenir 4.1.1.2. LDS ve LES: LDS ve LES komutları, bir 16-bit saklayıcıya bir ofset adres ve DS (LDS ile) veya ES (LES ile) segment saklayıcısına 6yeni bir segment adresi yükler. Bu komutlar, yeni ofset ve segment numarasını seçmede, değişik geçerli adresleme modlarından herhangi birisi kullanılır. Bu komutlardan her birinde hafızadan mikroişlemciye iki tane 16-bit kelime, yani toplam 4-byte veri transferi olur. LDS ve LES komutları ile, bir program içinde farklı bir DS ve ES alanlarına işaret edilirken, ofset saklayıcılara da yeni ofset yüklenir. Şekil.4.1’de LDS BX,[SI] komutu ile SI ile işaretli hafıza alanından bir 32-bit sayı BX ve DS saklayıcılarına kopyalanmaktadır. 39 4.2. Dizi (String) Komutları: Üç çeşit dizi (string) veri transfer komutu vardır. Bunlar: LODS, STOS ve MOVS. Bu komutlar, mikroişlemci ile hafıza arasında, bir blok veya tek bir byte veya kelime transferinde kullanılır. Bu komutları tanıtmadan, aşağıda önce, bu komutların kullanımında önemli olan, yön (direction) bayrağı (D) ve dizi işlemlerinde kullanılan DI ve SI saklayıcılarının fonksiyonları anlatılacaktır. DS Hafıza 10000 LDS BX,[SI] (DS) 2034 AX BX 20 34 SP BP SI DI 2000 CS DS 3000 34 20 00 30 12000 12001 12002 12003 1000 1FFFF Şekil.4.1 LDS BX,[SI] komutu yürütülürken bellek saklayıcılarının durumları. 4.2.1.Yön Bayrağı (D): Yön bayrağı dizi işlemleri sırasında, DI ve SI saklayıcıları için otomatik-arttırma (D = 0) veya otomatik-azalma (D = 1) çalışma modunu seçer. D bayrağı CLD komutu ile 0’lanır ve STD komutu ile 1’lenir. Yani CLD otomatik-arttırmayı ve STD otomatik-azalmayı seçer. Bir dizi komutu ile yapılan veri transferinden sonra, D bayrağıyla seçilen çalışma moduna göre, eğer veri 1-byte ise DI ve/veya SI 1 arttırılır veya azaltılır. Benzeri şekilde, transfer edilen veri 2 byte ise, bu kez DI ve/veya SI 2 arttırılır ya da azaltılır.DI ve SI Bir dizi komutunda DI, SI veya her ikisi kullanılabilir. Normalde SI, DS için ve DI, ES için ofset adres olmaktadır. SI için segment atanması, bir segment ön eki (override prefix) ile değiştirilebilir. Bununla beraber DI segment ataması her zaman ES’tir bu atama değiştirilemez. 40 4.2.2.LODS (Load String) LODZ komutu SI ile işaretli hafıza hücresinden AL’ye 1 byte veya AX’e 2 byte (kelime) yüklemektedir. Tablo.4.2, LODS komutunun bazı kullanım örneklerini göstermektedir. LODSB ve LODSW komutları bir byte veya bir kelime transferine neden olur. Örneğin, LODSB komutu yürütülürken, önce SI ile işaretli DS alanında bir byte veri AL saklayıcısına kopyalanır. Hemen sonra, SI, D bayrağının durumuna göre, 1 arttırılır veya azaltılır. 4.2.3.STOS (Store String): STOS komutu, AL veya AX’i DI ile işaretli hafıza hücresine saklanmaktadır. Tablo.4.3 STOS komutunun bazı kullanım örneklerini göstermektedir. LODS’te olduğu gibi, STOS’tan sonra B veya W kullanılarak bir byte veya kelime yapıldığı belirtilir. Tablo.4.2. LODS komutunun bazı değişik kullanım örnekleri. Asembly Dili Yapılan İşlem LODSB AL=[SI],SI=SI±1 LODSW AX=[SI],SI=SI±2 LODS BUFFER AL=[SI],SI=SI±1 (Eğer BUFFER byte ise) LODS DATA AX=[SI],SI=SI±2 (Eğer DATA Word ise) Tablo.4.3. STOS komutunun bazı değişik kullanım örnekleri. Asembly Dili Yapılan İşlem STOSB DI=AL,DI=DI±1 STOSW DI=AX,DI=DI±2 STOS BUFFER AL=AL,DI=DI±1 (Eğer BUFFER byte ise) STOS DATA AX=AX,DI=DI±2 (Eğer DATA Word ise) 41 4.2.4.REP ile STOS Komutu: Tekrar (repeat) REP öneki (prefix) herhangi bir dizi komutuna eklenebilir. Bu önek, bir dizi işleminin, CX sayma değeri sıfır oluncaya kadar devan etmesine neden olur. Aşağıda verilen örnek program parçasında, BUFFER adresli yerden başlayan 10 byte, sıfır ile temizlenmektedir. Bu işlem peş peşe 10 tane STOS komutuyla veya REP öneki ile bir tane STOS komutuyla yapılabilir. Program ES ve DI saklayıcılarını hafıza adresiyle yükleyen LES komutuyla başlamaktadır. Daha sonra, CX sayacı yüklenmekte ve DI bayrağı sıfırlanarak, her STOS komutu yürütüldükten sonra DI’nın otomatik arttırılması sağlanır. ; STOS komutunu kullanarak bir hafıza bloğunu temizleme LES DI, BUFFER ; BUFFER adresini yükle MOV CX, 10 CLD MOV AL, 10 REP STOSB ; sayacı yükle ; otomatik-arttırmayı seç ; hafıza temizlenecek ; BUFFER alanı temizle Yukarıda verilen programda, LES komutuyla yüklenen adres BUFFER kullanılan assembler’da bir yol ile tanımlanmalıdır. Genellikle DD (Define-Double Word) yalancı-işlemi (pseudooperation) 32-bit hafıza işaretçisi tanımlamada kullanılır. Hafıza bloğunu temizlemenin, daha hızlı bir yolu REP STOSW komutunu kullanmaktır. Bu durumda sayaç 5 ile yüklenmelidir. Çünkü 5 tane 0000h kelimesi 10 byte hafıza temizler. Aşağıda bu işlemi yapan program parçası verilmiştir. ; STOS komutunu kullanarak bir hafıza bloğunu temizleme LES DI, BUFFER ; BUFFER adresini yükle MOV CX, 5 CLD MOV AL, 0 REP STOSW ; sayacı yükle ; otomatik-arttırmayı seç ; hafıza temizlenecek ; BUFFER alanı temizle 4.2.5.MOVS (Move String): En güçlü dizi veri transfer komutu olan MOVS hafızanın bir alanından diğer bir alanına bir byte veya bir kelime aktarımı yapılır. Diğer bir deyişle, bu komut hafızadan hafızaya veri transferi 42 yapar. Bir MOVS komutu, data segment’te (DS) bulunan ve SI saklayıcısı ile adreslenen hafıza hücresini, ES’de bulunan ve DI ile adreslenen hafıza alanına aktarır. Tablo.4.4’te MOVS komutunun bazı değişik kullanımları gösterilmektedir. Tablo.4.4. MOVS komutunun bazı değişik kullanım örnekleri. Asembly Dili Yapılan İşlem MOVSB [DI]=[SI],DI=DI±1,SI=SI±1 MOVSW [DI]=[SI],DI=DI±2,SI=SI±2 MOVS BYTE1,BYTE2 [DI]=[SI],DI=DI±1,SI=SI±1 MOVS WORD1,WORD2 [DI]=[SI],DI=DI±2,SI=SI±2 Aşağıdaki verilen örnek program parçasında, BUFFER2 alanından 100 byte BUFFER1 lanına aktarılmaktadır. MOVS kullanılmadan önce, LES ve LDS komutlarıyla hafıza işaretçileri DI ve SI yüklenerek, BUFFER1 ve BUFFER2 alanlarını işaret eder. Daha sonra, MOVS komutu yürütülürken, SI ve DI’da bulunan adreslerin otomatik arttırılması, CLD komutuyla seçilmiş ve CX sayacı 100 ilk değeriyle yüklenmiştir. Bu ön işlemlerden sonra, REP komutuyla kullanılan MOVS komutu veri transferini gerçekleştirir. LES DI, BUFFER1 ; BUFFER1 adresini yükle LES SI, BUFFER2 ; BUFFER2 adresini yükle CLD ; otomatik-arttırmayı seç MOV CX, 100 REP MOVSB ; 100 byte veri transferi ; BUFFER2’den BUFFER1’e aktarım 4.3.Diğer Veri Transfer Komutları: Bu gruptaki veri transfer komutaları, çok önemli olmalarına ve çok kullanılmalarına karşın daha önceki gruplara girmemektedir. Bu komutlar IN, OUT; XCHG, XLAT, LAHF ve SAHF ’dir. 4.3.1. IN ve OUT: Mikroişlemci bu komutlar ile giriş/çıkış cihazları (port’ları) ile haberleşir. 8085A mikroişlemcisinde IN ve OUT komutlarından her biri 2 byte olup birinci byte işlem kodu sonraki 43 byte prot adresidir. Bu sayede, 8085A, 256 tane giriş ve 256 tane çıkış olmak üzere toplam 512 tane port’a sahip olabilir. 8085A’da veri aktarımı, mikroişlemcinin A (accumulator) saklayıcısı ile 8-bit bir sabit adres ile belirtilen (adreslenen) bir dış port arasında olur. 8086/8088 mikroişlemcilerinde veri aktarımı mikroişlemcinin AL veya AX saklayıcısı ile bir sabit adres ile veya DX ile belirtilen (adreslenen) ir dış port arasında olur. Tablo.4.5’te IN ve OUT komutlarının bazı değişik kullanım örnekleri verilmektedir. Tablo.4.5. IN ve OUT komutlarının bazı değişik kullanım örnekleri. Asembly Dili Yapılan İşlem IN AL,IPORT IPORT’tan 8-bit veri AL’ye okunur IN AX,IPORT IPORT’tan 16-bit veri AX’ye okunur IN AL,DX DX ile işaretli port’tan 8-bit veri AL’ye okunur IN AX,DX DX ile işaretli port’tan 16-bit veri AX’e okunur OUT OPORT,AL AL’nin içeriği OPORT’a gönderilir OUT OPORT,AX AX’in içeriği OPORT’a gönderilir OUT DX,AL AL’nin içeriği DX ile işaretli port’a gönderilir OUT DX,AX AX’in içeriği DX ile işaretli port’a gönderilir 4.3.2.XCHG: Bu komut, herhangi bir saklayıcının içeriğini diğer bir saklayıcı veya hafıza hücresiyle değiştirmektedir. XCHG komutu, segment saklayıcılarının içeriğini ve hafızadan hafızaya veri içeriği değiştirmede kullanılmaz. XCHG komutunu 16-bit AX saklayıcısı ile diğer bir 16-bit saklayıcının içeriklerini değiştirmede kullanılan en etkin ve en hızlı yer değiştirme yönetimidir. Çünkü,bu komut hafızada bir byte yer kaplar. Diğer XCHG komutları, kullanılan adresleme moduna göre, 2 veya daha fazla byte gerektirir. Tablo.4.6, XCHG komutunun bazı değişik kullanım örnekleri verilmektedir. Tablo.4.6. XCHG komutunun değişik şekilleri. 44 Asembly Dili Yapılan İşlem XCHG saklayıcı,saklayıcı Saklayıcı içeriklerini değiştir. XCHG saklayıcı,hafıza Saklayıcı ile hafıza içeriklerini değiştir. 4.3.3.XLAT: XLAT (translate) komutu, AL’nin içeriğini hafızada bir tabloda saklı sayıya çevirmektedir. Bu komut, bir kodu diğerine çeviren, doğrudan tablo arama (table lookup) tekniğinde kullanılır. XLAT komutu, önce AL’nin içeriğini BX saklayıcısına ekleyerek DS için bir hafıza adresi oluşturur. Daha sonra bu adreste saklı veriyi AL saklayıcısına yükler. Örneğin: bir 7-segment LED gösterge arama tablosunun DISPLAY adresine saklandığını varsayalım. XLAT komutu, AL saklayıcısında bulunacak 0 ile 9 arasında değişecek BCD (binary Coded Decimal) sayıların 7-segment kod karşılığı bulmada kullanılır. MOV BX, OFFSET DISPLAY ; DISPLAY adresini yükle XLAT ; AL’deki BCD kodu 7-segment koda çevir 4.3.4.LAHF ve SAHF: Bu komutlar 8085 mikroişlemcisinin yazılımını 8086/8088 çevirmek için tasarlanmıştır ve seyrek olarak kullanılmaktadır. LAHF komutu bayrak saklayıcısının en sağdaki 8-bit’ini AH saklayıcısına yüklemektedir. SAHF komutu ise AH saklayıcısını bayrak saklayıcısının en sağdaki 8-bit’ine aktarmaktadır. 4.4.Aritmetik ve Lojik Komutlar:( Toplama, Çıkarma ve Karşılaştırma) Bir mikroişlemcinin komut kümesindeki en temel aritmetik komutlar, toplama, çıkarma, ve karşılaştırma işlemleridir. Bu bölümde toplama komutları ADD, ADC ve INC; çıkarma komutları SUB, SBB, DEC ve karşılaştırma komutu CMP sunulacaktır. 4.4.1.Toplama( ADD, ADC ve INC Komutları): Temel olarak ADD ve ADC olmak üzere iki toplama komutu olmasına karşın, kullanılan adresleme modlarına göre, toplama işlemi çok değişik şekiller almaktadır. İkinci elde ile toplama komutu ADC (Add with Carry) değişik uzunlukta (16-bit, 32-bit, 64-bit veya daha uzun) operandların toplama işleminde kullanılır.INC(arttırma) komutu bir operand’a 1 toplayan diğer bir toplama komutu sayılabilir. 45 4.4.1.1.ADD Komutu: Tablo.4.7, ADD toplama komutunun değişik adresleme modlarına göre bazı kullanım örneklerini göstermektedir. Tablonun başında saklayıcı toplamasına (register addition) çeşitli örnekler verilmiştir. Bu toplamada her iki operand bir saklayıcıdan gelmektedir. Tablo .4.7. Toplama komutunun değişik kullanım örnekleri. Asembly Dili Yapılan İşlem ADD AL,CL AL = AL + CL ADD DX,SI DX = DX + SI ADD BL,20H BL = BL + 20H ADD CX,4000H CX = CX + 4000H ADD [BX],CL CL,BX ile adreslenen DS’deki hücre ile toplanır, sonuç yine bu hücreye yazılır. ADD CX,[SI+2] CX,SI+2 ile adreslenen DS’de bulunan hücre ile toplanır, sonuç CX’e yazılır. ADD AL,BUF AL,DS’de bulunan BUF hücresi ile toplanır,sonuç AL’ye yazılır. ADD AL,DS’de bulunan BUF ve ofset DI’nın toplamıyla adreslenen hücre AL,BUF[DI] ile toplanır, sonuç AL’e yazılır. ADD DS’de bulunan BX ve ofset DI’nın toplamı ile adreslenen hücre, DL [BX+DI],DL ile toplanır ve sonuç yine bu hafıza hücresini yazılır. Diğer bir adresleme ivedi toplama (immediate addition) adreslemesidir. Bu adreslemede, bir operand saklayıcıdan,diğer bir operand hafızadan gelen sabit bir sayıdır. SI, DI, BP veya BX saklayıcılarıyla yapılan adreslemeyle hafızadan saklayıcıya toplama (memory-to-register addition) gerçekleştirilir. Bir taban ofset değerinin toplanmasıyla oluşan adresle işaretlenen hücrenin bir saklayıcı ile toplanması ile dizi toplaması (array addition) gerçekleştirilir. Aşağıda verilen örnekte, bir byte dizisi olan ARRAY’in ilk 3 elemanı ARRAY[0], ARRAY[1] ve ARRAY[2] toplanmaktadır. 46 MOV AL, 0 ; DISPLAY adresini yükle MOV SI, 0 ; DISPLAY adresini yükle ADD AL, ARRAY[SI] ; ilk eleman ADD AL, ARRAY[SI+1] ; ikinci eleman ADD AL, ARRAY[SI+1] ; üçüncü eleman 4.4.1.2.ADC Komutu: Elde ile toplama komutu olan ADC, operand ile beraber elde bayrağını (C) toplamada kullanır. Bu komut 8086-8088 ’da 16-bit’ten ve 80386 – Pentium ’da ise 32-bit’ten daha geniş sayıları toplamada kullanılır. Tablo.4.8, ADC komutunun bazı kullanım şekillerini göstermektedir. Tablo.4.8. ADC komutunun değişik kullanım örnekleri Asembly Dili Yapılan İşlem ADC AL,CL AL = AL + CL + C ADC AX,BX AX = AX + BX + C ADC [BX],AL DS’de bulunan BX ile adreslenen byte hücresi,AL ve C ile toplanır, sonuç hafızada saklanır. ADC AX,[BP+2] SS’deki BP+2 ile adreslenen 16-bit hafıza hücresi,AX ve C ile toplanır, sonuç AX’de saklanır. 4.4.1.3.INC Komutu: Bu komut bir segment saklayıcısı dışında herhangi bir saklayıcıya veya bir hafıza hücresine 1 eklemektedir. Tablo.4.9, INC komutunun bazı kullanım şekillerini göstermektedir. Tablo.4.9. Arttırma komutunun değişik kullanım örnekleri Asembly Dili Yapılan İşlem INC CL CL = CL + 1 47 INC BP BP = BP + 1 INC BYTE DS’de bulunan BX ile adreslenen bir byte hafıza içeriği arttırılır. PTR[BX] INC WORD DS’de bulunan SI ile adreslenen bir 16-bit hafıza içeriği arttırılır. PTR[SI] 4.4.2.Çıkarma( SUB, SBB ve DEC Komutları): Temel olarak SUB ve SBB olmak üzere iki çıkarma komutu olmasına karşın kullanılan adresleme modlarına göre çıkarma işlemi çok değişik şekiller almaktadır. İkinci ödünç ile çıkarma komutu SBB (Subtract with Borrow) değişik uzunlukta (16-bit, 32-bit, 64-bit veya daha uzun) operandların çıkarma işleminde kullanılır. DEC (azaltma) komutu bir operand’tan 1 çıkaran diğer bir çıkarma komutu sayılabilir. 4.4.2.1.SUB Komutu: Tablo.4.10, SUB komutunun değişik adresleme modlarına göre bazı kullanım örneklerini göstermektedir. Tablo.4.10. Çıkarma komutunun değişik kullanım örnekleri Asembly Dili Yapılan İşlem SUB AL,CL AL = AL - CL SUB DX,SI DX = DX - SI SUB BL,20H BL = BL - 20H SUB CX,4000H CX = CX - 4000H SUB [BX],CL BX ile adreslenen DS’deki hücreden CL çıkarılır, sonuç yine bu hücreye yazılır. SUB CX,[SI+2] CX’den SI+2 ile adreslenen DS’de bulunan hücre çıkartılır, sonuç CX’e yazılır. 48 SUB AL,BUF AL’den DS’de bulunan BUF hücresi çıkartılır,sonuç AL’ye yazılır. SUB AL’den ,DS’de bulunan BUF ve ofset DI’nın toplamıyla adreslenen AL,BUF[DI] hücre çıkartılır, sonuç AL’e yazılır. SUB DS’de bulunan BX ve ofset DI’nın toplamı ile adreslenen hücreden [BX+DI],DL DL çıkartılır ve sonuç yine bu hafıza hücresini yazılır. 4.4.2.2.SBB Komutu: Ödünç ile toplama komutu olan SBB, operand ile beraber elde bayrağını (C) çıkarmada kullanır. Bu komut Bu komut 8086-8088 ’da 16-bit’ten ve 80386 – Pentium ’da ise 32-bit’ten daha geniş sayıları toplamada kullanılır. Tablo.4.11, SBB komutunun bazı kullanım şekillerini göstermektedir. Tablo.4.11. SBB komutunun değişik kullanım örnekleri Asembly Dili Yapılan İşlem SBB AL,CL AL = AL - CL - C SBB AX,BX AX = AX - BX - C SBB [BX],AL DS’de bulunan BX ile adreslenen byte hücresinden AL ve C çıkartılır, sonuç hafızada saklanır. SBB AX,[BP+2] AX’ten SS’deki BP+2 ile adreslenen 16-bit hafıza hücre ve C çıkartılır, sonuç AX’te saklanır. 4.4.2.3.DEC Komutu: Bu komut bir segment saklayıcısı dışında herhangi bir saklayıcıdan veya bir hafıza hücresinden 1 çıkarmaktadır.Tablo.4.12,DEC komutunun bazı kullanım şekillerini göstermektedir. 49 Tablo.4.12. Azaltma komutunun değişik kullanım örnekleri Asembly Dili Yapılan İşlem DEC AL AL = AL - 1 DEC SP SP = SP - 1 DEC BYTE DS’de bulunan BX ile adreslenen bir byte hafıza içeriği azaltılır. PTR[BX] DEC WORD DS’de bulunan SI ile adreslenen bir 16-bit hafıza içeriği azaltılır. PTR[SI] 4.4.3.Karşılaştırma: Karşılaştırma komutu olan CMP (Compare) sadece bayrak bit’lerini değiştiren bir çıkarma işlemidir. Karşılaştırma işlemi, bir saklayıcı içeriğiyle diğer bir saklayıcı veya hafıza içeriği arasında yapılır. Genelde, bu karşılaştırma komutundan hemen sonra bayrakların durumunu test eden bir dallanma komutu gelir. Tablo.4.13, CMP komutunun değişik adresleme modlarına göre bazı kullanım örneklerini göstermektedir. Karşılaştırma komutu daha önce verilen toplama ve çıkarma komutunda olduğu gibi aynı adresleme modlarını kullanmaktadır. Sadece hafızadan-hafızaya ve segment saklayıcı karşılaştırmasına izin verilmez. Karşılaştırma işlemine giren operand’larda bir değişme olmaz. Sadece bayraklar etkilenir. Tablo .4.13. Karşılaştırma komutunun değişik kullanım örnekleri Asembly Dili Yapılan İşlem SUB AL,CL AL-CL işlemi yapılır. SUB DX,SI DX-SI işlemi yapılır. 50 SUB BL,20H BL-20H işlemi yapılır. SUB CX,4000H CX-4000H işlemi yapılır. SUB [BX],CL BX ile adreslenen DS’deki hücreden CL çıkartılır. SUB CX,[SI+2] CX’ten SI+2 ile adreslenen DS’te bulunan hücre çıkartılır. SUB AL,BUF AL’den DS’de bulunan BUF hücresi çıkartılır. SUB Al’den DS’de bulunan BUF ve ofset DI’nın toplamı ile adreslenen AL,BUF[DI] hücre çıkartılır. SUB DS’de bulunan BX ve ofset DI’nın toplamı ile adreslenen [BX+DI],DL hücreden DL çıkartılır. 4.5.Çarpma ve Bölme: Eski 8-bit mikroişlemciler donanım çarpma-bölme birimine sahip değildi. Bu birim 16-bit mikroişlemcilere eklenen ilk önemli donanım birimi oldu. Bu temel birim, bununla beraber, programlara sadece tamsayı (integer) çarpma ve bölme desteği sağlamaktadır. Kayan nokta işlemleri ya yazılım alt programları ile veya ilk zamanlar, 8087 (8086/8088 için), 80287 (80286 için) ve 80387 (80386 için) gibi bir dış nümerik işlemciyle sağlandı. 80486 ve daha sonraki Pentium işlemcilerde, kayan nokta aritmetik işlemleri, artık tüm devre üzerinde gerçekleştirildi. 4.5.1.Çarpma: Çarpma işlemi, 8-bit veya 16-bit işaretsiz (MUL) veya işaretli (IMUL) tamsayılar üzerinde yapılır. Çarpma sonucu (çarpım), operand’lar 8-bit ise, 16-bit; 16-bit ise 32-bit olur. Çarpma komutlarında, ivedi adresleme modunun dışındaki adresleme modları kullanılabilir. Çarpma ve bölme komutlarında ilk operand her zaman AL (8-bit işlemde) veya Ax (16-bit işlemde) saklayıcısında bulunur. a) 8-Bit Çarpma: 8-bit çarpma işleminde çarpanlardan biri her zaman AL saklayıcısında bulunur. Programcı ikinci çarpanı komut ile belirtir. Şekil.4.1’de görüldüğü gibi 16-bit çarpım sonucu Ax saklayıcısında bulunur. 51 Operand8 X AL AX Şekil.4.1. 8-bit çarpma işlemi: İşaretli çarpmada operand’lar donanım tarafından işaretli (2’nin tümleyeni) olarak yorumlanır ve çarpım yine 2’nin tümleyeni şeklinde olur. Bu tür çarpma işleminde IMUL komutu kullanılır. Sayıların yorumlanması ve işlemleri programcıya bağlıdır. b) 16-Bit Çarpma: 16-bit çarpma işleminde çarpanlardan biri her zaman AZ saklayıcısında bulunur. Programcı ikinci çarpanı komut ile belirtir. Şekil.4.2’ de görüldüğü gibi 32-bit çarpım sonucu DX ve AX saklayıcılarında bulunur. Tablo.4.14, MUL ve IMUL komutlarının değişik adresleme modlarına göre bazı kullanım örnekleri gösterilmektedir. Operand16 X AX DX AX Şekil.4.2. 16-bit çarpma işlemi Tablo.4.14. Çarpma komutunun değişik kullanım örnekleri Asembly Dili Yapılan İşlem MUL DL AL’de bulunan işaretsiz tamsayı DL ile çarpılır. Çarpım AX’te bulunur. IMUL CH AL’de bulunan işaretli tamsayı CH ile çarpılır. Çarpım AX’te bulunur. 52 MUL BYTE DS’de bulunan BX ile adreslenen hafıza hücresi AL ile çarpılır. PTR[BX] Çarpım AX’te bulunur. IMUL BYTE PTR DS’de OP2 adresinde bulunan işaretli tamsayı AL ile çarpılır. OP2 Çarpım AX’te bulunur. IMUL CX AX’deki işaretli tamsayı CX ile çarpılır. Çarpım DX:AX’te bulunur. MUL WORD DS’de bulunan ve SI ile adreslenen 16-bit hafıza hücresi AX ile PTR[SI] çarpılır. Çarpım DX:AX’te bulunur. 4.5.2.Bölme: 8086/8088’de çarpma işlemi gibi bölme işlemi de, işaretsiz (DIV) veya işaretli (IDIV) 8-bit veya 16-bit sayılar üzerinde yapılır. a) 8-Bit Bölme: 8-bit bölme işleminde bölünen her zaman AX saklayıcısında bulunur. Programcı bölen sayıyı komut ile belirtir. Şekil.4.3’te görüldüğü gibi 8-bit bölüm sonucu AL ve AH saklayıcılarında bulunur. AX Operand8 AL AH Şekil.4.3. 8-bit bölme işlemi Aşağıda verilen bölme işlemi örneğinde, AL saklayıcısındaki 12h sayısı CL saklayıcısındaki 2 sayısına bölünmektedir. Bölme işleminden temizlenmektedir. MOV AL, 12H MOV CL, 2 MOV AH, 0 DIV CL 53 önce kalan saklandığı AH saklayıcısı 8-bit bölme işleminde, bölünecek sayı 8-bit ise bu sayıyı 16-bit’e çevirmek için CBW (Convert Byte to Word) komutu kullanılır. Bu komut Al saklayıcısında bulunan işaretli 8-bit sayıyı AX saklayıcısına 16-bit olarak çevirir. Bu komut genellikle 8-bit bölme işleminden önce kullanılır. b)16-Bit Bölme: 16-bit bölme işleminde bölünen her zaman DX:AX saklayıcı çiftinde bulunur. Programcı bölen sayıyı komut ile belirtir. Şekil.4.4’de görüldüğü gibi, 16-bit bölüm sonucu AX ve DX saklayıcılarında bulunur. DX AX Operand8 AL DX Şekil.4.4. 16-bit bölme işlemi: 16-bit bölme işleminde, bölünecek sayı 16-bit ise bu sayıyı 32-bit’e çevirmek için CWD (Convert Word to Double Word) komutu kullanılır. Bu komut AX saklayıcısına bulunan işaretli 16-bit sayıyı DX:AX saklayıcı çiftine 32-bit olarak çevirir. Bu komut genellikle 16-bit bölme işleminden önce kullanılır. Aşağıda verilen örnekte, AX’teki –200 CX’te bulunan 9 ile bölünmektedir. Bölme işlemindeki önce CWD komutu ile AX’teki işaretli sayı DX:AX saklayıcı çiftine 32-bit olarak çevrilir. Bölme işleminden sonra AX’te bölüm (-22) ve DX’te kalan (-2) bulunur. Tablo.4.15’’de 8-bit ve 16-bit bölme işlemlerine ait bazı örnekler verilmektedir. MOV AX, -200 MOV CX, 9 CWD IDIV CX Tablo.4.15. Bölme komutunun değişik kullanım örnekleri Asembly Dili Yapılan İşlem 54 DIV DL AL’de bulunan işaretsiz tamsayı DL ile bölünür. Çarpım AX’te bulunur. IDIV CH AL’de bulunan işaretli tamsayı CH ile bölünür. Çarpım AX’te bulunur. DIV BYTE PTR[BX] DS’de bulunan BX ile adreslenen hafıza hücresi AL ile bölünür. Çarpım AX’te bulunur. IDIV BYTE PTR DS’de OP2 adresinde bulunan işaretli tamsayı AL ile bölünür. OP2 Çarpım AX’te bulunur. IDIV CX AX’deki işaretli tamsayı CX ile bölünür. Çarpım DX:AX’te bulunur. DIV WORD PTR[SI] DS’de bulunan ve SI ile adreslenen 16-bit hafıza hücresi AX ile bölünür. Çarpım DX:AX’te bulunur. 4.6.BCD ve ASCII Aritmetik: 8086/8088 ikili kodlanmış ondalık (Binary Coded Decimal - BCD) ve ASCII sayılar üzerinde işlem yapan özel konutlara sahiptir. Bu komutlar, bu tür kodları kullanan nümerik veri göstergelerini sürmede veya benzeri diğer veri işlemlerinde faydalıdır. 4.6.1.BCD Aritmetik: BCD aritmetikte kullanılan 4 komut vardır. Bu komutlar şunlardır: DAA (Decimal Adjust after Addtion) DAS (Decimal Adjust after Subtraction) AAM (Adjust After Mutiplication) AAD (Adjust Before Division) DAA, DAS, AAM komutları BCD sayıların toplama, çıkarma, çarpma işlemlerinden sonra; ADD ise DIV komutu kullanmadan önce sayıları ayarlama için kullanılır. 55 Toplama ve çıkarmada, toplanacak ve çıkartılacak sayılar, bir byte içinde, 2 hane olarak AL’de saklanır. Bu işleme paketlenmiş BCD formatı denir. Örneğin, eğer bir byte 25H ise ve bu bir BCD sayıyı belirtiyorsa, bu sayı BCD kodlu 25 sayıdır. Yani bu byte 2 ve 5 BCD hanelerini işlemektedir. Çarpma ve bölmede, sayılar 1 byte’ta 1 hane olarak paketlenmiş BCD sayıları olarak saklanır. Örneğin, AL 04 ise, sayı BCD 4 ‘e karşılık gelir. 4.6.1.1.DAA: DAA komutunun kullanımına ait aşağıda verilen örnek, BX ve CX saklayıcılarında bulunan 4 haneli BCD sayıları toplamakta, sonucu DX saklayıcısına saklamaktadır. İlk DAA komutunun kullanımından önce, 99 ve 34 sayıları toplanarak BCD olmayan CD sayısı üretilmiştir. DAA komutu bu işlemi C bayrağında 1 ve AL’de 33 yaparak düzeltmektedir. Daha sonra 12 ve 30 elde bayrağıyla beraber toplanmaktadır. Bu sayının haneleri BCD olduğundan, ikinci DAA komutundan sonra bu sayıda bir değişiklik olmaz.sonuç olarak, DX saklayıcısında 4333H veya 4333 BCD kodu bulunur. MOV CX, 1234H MOV CX, 3099H MOV AL, BL DIV AL, CL DAA MOV DL, AL MOV AL, BH ADC AL, DH DAA MOV DH, AL Yukarıdaki toplama işlemi DAA komutu kullanılmadan yapılsaydı çok daya uzun olacaktı. DAA komutu, otomatik olarak AL’de bulunan sayıları düzelttiği için programcıya bu işlemi kontrol yükü düşmez. 4.6.1.2.DAS: DAS komutu DAA gibi çalışmaktadır. Bu komut çıkarma işleminden sonra AL’yi ayarlamada kullanılır. Aşağıdaki program DAS komutu kullanılarak, iki BCD sayının çıkartma işlemini gerçekleştirmektedir. Bu program yukarıda verilen programa çok benzemektedir. ADD ve ADC 56 komutları SUB ve SBB ile DAA komutu DAS ile yer değiştirilmiştir. Bu program çalıştırıldığında DX saklayıcısında 1865 BCD sayısı bulunur. MOV CX, 1234H MOV CX, 3099H MOV AL, BL DIV AL, CL DAS MOV DL, AL MOV AL, BH ADC AL, DH DAS MOV DH, AL 4.6.1.3.AAM: Bu komut iki tane tek haneli paketlenmiş BCD sayının çarpma işleminden sonra kullanılır. Örneğin, AL saklayıcısında bulunan 5 ile CL’deki 6 sayılarını çarpan aşağıdaki örneği düşünelim. Çarpma işleminden sonra AX saklayıcısında 1EH (30) bulunur. Bu BCD olarak doğru bir gösterim değildir. AAM komutundan sonra AX saklayıcısı 0300H veya 2 haneli paketlenmiş 30 BCD sonucuna çevrilir. MOV AL, 5 DIV CL, 6 MUL AAM 4.6.1.4.AAD: Bir aritmetik işlemden sonra kullanılan diğer 3 BCD komutundan farklı olarak, bu komut bölme işleminden önce kullanılmaktadır. AAD komutu, AX saklayıcısında 2-haneli paketlenmiş bir BCD sayı gerektirmekte olup AH en değerli haneyi, AL ise diğer haneyi tutar. Bu 2-haneli BCD sayı, tek-haneli bir BCD sayı ile bölünmeden önce AAD komutuyla ayarlanmalıdır. Bu sayede yapılan bölme işlemi sonucunda, AL saklayıcısında tek-haneli sonuç ve AH’te kalan üretir. AAD komutu paketlenmiş BCD sayıları 00 ile 99 arasında ikili sayılara çevirir. Aşağıda 57 verilen örnek paketlenmiş BCD 72 sayısının 9 ile bölünme işlemini gerçekleştirmektedir. AAD komutuyla AX saklayıcısına bulunan 0702H sayısı, yine AX’te 0048H sayısına çevrilir. Bu şekilde BCD sayı ikili sayıya çevrilir. Böylece, ikili bölme komutu DIV ile doğru bölme işlemi yapılarak, AL’de 08H ve AH’ta 00H bulunur. MOV BL, 9H DIV AX, 0702H AAD DIV BL 4.6.2.ASCII Aritmetik: ASCII aritmetik komutları, ASCII-kodlu sayılarla kullanılır. Bu sayılar 30H ile 39H arasında değişir ve 0 ile 9 arasında sayıları gösterir. ASCII-kodlu sayılarla kullanılan iki komut vardır. Bu komutlar şunlardır. AAA (Adjust for ASCII Addition) AAS (Adjust for ASCII Substraction) Bu komutlar her zaman AX saklayıcısını ayarlama işleminden önce kaynak ve sonra hedef olarak kullanılır. 4.6.2.1. AAA: İki 1-haneli ASCII-kodlu sayının toplanması faydalı bir veri üretmez. Örneğin, eğer 31H ile 39H sayılarını toplarsak, sonuç 6AH olur. bu ASCII toplama (1+9) işlemi, 10 ondalık sayısına karşılık gelen, 31H ve 30H ASCII-kodlu 2-haneli bir ASCII sonucu üretmeli. Eğer bu toplamadan sonra, AAA komutu yürütülürse, AX saklayıcısı 0100H içerir. Bu sonuç ASCII olmamakla beraber, 3030H eklenerek, ASCII koda çevrilir ve 3130H elde edilir. Aşağıda verilen kod parçası yukarıda anlatılan işlemi gerçekleştirmektedir. MOV AX, 031H DIV AL, 39H AAA ; ASCII 1 yükle, AH2i temizle ; ASCII 9 ile topla ; ASCII toplama sonu ilk ayarlama ADD AX, 3030H ; Sonucu ASCII olarak ver 58 4.7.Lojik İşlemler: Lojik işlemler, düşük-seviyeli bir programda, ikili bit kontrolü sağlar. Lojik işlemler bit’lerin temizlenmesini (0’lanmasını), 1’lenesini veya tersinin alınmasını sağlar. Bütün lojik işlemler bayrak bit’lerini etkiler. Lojik işlemler her zaman elde ve taşma bit’lerini temizleyip diğer bayraklar sonucun durumunu yansıtır. Temel lojik komutları AND, OR, XOR (Exclusive-OR) ve NOT işlemleridir. Diğer bir lojik komut olan TEST, AND komutunun özel bir şeklidir. NOT komutuna benzeyen NEG de bu bölümde anlatılacaktır. 4.7.1.AND, OR ve XOR Komutları: AND işlemi lojik çarpma işlemini gerçekleştirir. AND işlemi, bir ikili sayıdaki bit’leri temizleme işleminde kullanılabilir. Bir ikili sayıdaki bit’i temizleme (0’lama) işlemine maskeleme (masking) denir. Bu işlem bir veri kelimesinde istenmeyen bit’ler temizlenir. Maskeleme işlemine bir örnek olarak bir 16-bit ASCII bilginin BCD koda çevrilmesini düşünelim. Aşağıdaki örnekte olduğu gibi, eğer ASCII koddaki her bir veri hanesinin en sol 4 bit’i temizlenirse (maskelenirse) BCD kod elde edilir. MOV CX, 3531H ; 2 haneli ASCII sayıyı yükle AND CX, 0F0FH ; CX’i maskele OR işlemi lojik toplama işlemini gerçekleştirir. OR işlemi ikili sayıdaki istenilen bit’leri 1’leme işleminde kullanılabilir. Aşağıda verilen örnekte, iki sayı çarpıldıktan sonra AAM komutu kullanılarak 2-haneli paketlenmiş BCD sayıya çevrilmektedir. En son satırda yapılan OR işlemiyle, bu sayı 2-haneli ASCII-kodlu sayıya çevrilir. OR komutundan önce AX saklayıcısı 0305H içermektedir. OR komutundan sonra AX 3335H içerir. MOV AL, 5 ; Veriyi yükle AND BL, 7 MUL BL AAM ; AX = 5 * 7 ; Paketlenmiş 2-haneli BCD ayar OR AX, 3030 ; ASCII’ye çevir 59 XOR işlemi, bazen karşılaştırma işlemi olarak adlandırılır.XOR işleminde girişlerin farklı olma durumunda; örneğin, γ = A XOR B işleminde, A = 1, B = 0, veya, A = 0, B = 1 ise, sonuç γ lojik 1 olur. Diğer durumlarda γ lojik 0’dır. XOR işlemi bir saklayıcının veya bir hafıza hücresinin bit’lerini tersleme (invert) işleminde kullanılabilir. Bu kelimedeki tersini alınacak bit’lerin karşılığı 1 ile XOR işlemine girer ise, istenen bit’ler terslenir. Bu işlem, bir kontrol uygulamasında açma/kapama bit’lerinin konumlarını değiştirmede yararlıdır. Örneğin, AX saklayıcısında bulunan bit’lerin, en sağdaki 6 bit’i değiştirilmeden en-solundaki 10 bit’inin tersi alınmak istensin. Aşağıdaki komut bu işlemi gerçekleştirmektedir. XOR AX, 0FFC0H Bir saklayıcının veya bir hafıza hücresinin bit’leri, kendisi ile XOR işlemine girer ise o kelime temizlenir. Bu işlem en hızlı kelime temizleme işlemidir. Örneğin, aşağıda verilen kod örneğinde AL saklayıcısı temizlenmektedir. XOR AL, AL AL saklayıcısını temizleyen MOV komutu ile verilen aşağıdaki örneği hafızadan işlem kodundan sonra, 0 verisini okuma için bir hafıza okuma çevrimi daha gerçektir. Bu yüzden, sadece bir XOR işlem kodundan okumasıyla AL’yi temizleyen yukarıdaki koda göre yürütme süresi daha uzun. MOV AL, 0 Özet olarak, AND komutu bit’leri temizlemekte (0’lamakta), OR komutu 1’lemekte ve XOR komutu ise bit’lerin tersini almaktadır. Bu üç komut bir programcıya, herhangi bir saklayıcıda veya hafıza hücresinde bulunan bit bit üzerinde kontrol sağlar. Tablo.4.16, AND, OR ve XOR komutlarının değişik adresleme modlarına göre bazı kullanım örnekleri gösterilmektedir. Tablo.4.16. AND, OR ve XOR örnekleri (OP[Operation]: AND, OR ya da XOR) Asembly Dili Yapılan İşlem OP AL,CL AL = AL OP CL OP CX,DX CX = CX OP DX 60 OP BL,0FH BL = BL OP 0FH OP SI,00FFH SI = SI OP 00FFH OP AX,[DI] AX, data segment hafızada DI ile işaret edilen 16-bir kelime ile OP’lanır, sonuç AX’te saklanır. OP BUF[SI],AL Data segment hafızada BUF artı SI ile işaret edilen byte içerik OP’lanır, sonuç hafızada saklanır. 4.7.2.TEST Komutu: TEST komutu bir AND işlemi gerçekleştirir. Daha önce gördüğümüz, AND komutu, hedef operand’ı değiştirmektedir, fakat TEST komutu değiştirmez. Bu komut, testin sonucunu belirten, sadece bayrak saklayıcısının durumunu etkiler. TEST komutu AND komutu gibi aynı adresleme modlarını kullanır. Tablo.4.17, TEST komutunun bazı şekillerini göstermektedir. Tablo.4.17. TEST komutunun bazı kullanım örnekleri Asembly Dili Yapılan İşlem TEST AL,CL AL ile CL AND’lenir. Ne AL ne de CL değişir. Sadece bayraklar değişir. TEST CX,DX CX ile DX AND’lenir. Ne CX ne de DX değişir. Sadece bayraklar değişir. TEST BL,5 AL ile 5 AND’lenir. AL değişmez. Sadece bayraklar değişir. TEST SI,00FFH DX ile 00FH AND’lenir. DX değişmez. Sadece bayraklar değişir. TEST komutu bir karşılaştırma CMP (Compare) komutu gibi kullanılır. Bu komut normalde tek bir bit’i test eder; buna karşın, CMP komutu bütün bir byte’ı veya kelimeyi test eder. Sıfır bayrağı (Z), eğer test edilen bir sıfır ise, lojik 1’dir (Z=1, sonuç sıfır); eğer test edilen bit sıfır değil ise, lojik 0’dır (Z=0, sonuç sıfır değil). Genelde TEST komutundan sonra JZ (Jump Zero) veya JNZ (Jump Not Zero) gibi bir dallanma komutu kullanır. Aşağıda verilen kısa program parçasında, AL saklayıcısında bulunan en-sağdaki ve en-soldaki bit durumları test edilmektedir. 1 ile en-sağdaki 128 ile en-soldaki bit 61 pozisyonu seçilir. Her testi bir dallanma komutu takip eder. Eğer test edilen bit 1 değil ise, dallanma komutuyla belirtilen adrese (RIGHT veya LEFT) program akışı yönlenir. TEST AL, 1 ; en-sağdaki bit’i test et JNZ RIGHT ; eğer 1 ise dallan TEST AL, 128 ; en-soldaki bit’i test et JNZ LEFT ; eğer 1 ise dallan 4.7.3.NOT ve NEG Komutları: Lojik tersini alma işlemi (veya 1’in tümleyeni) NOT komutuyla ve aritmetik işaret tersleme işlemi (veya’nın tümleyeni) NEG komutuyla yapılır. Bu komutlar, sadece tek operand kullanan çok az komuttan ikisidir. Tablo.4.18, NOT ve NEG komutlarının değişik adresleme modlarına göre bazı kullanım örneklerini göstermektedir. NOT komutu, bir byte’taki veya kelimedeki bit’lerin tersini alır. NEG komutu ise, bir sayının 2’nin tümleyeni eşini bulur. Yani bir işaretli sayının aritmetik işareti pozitiften negatife veya negatiften pozitife değişir. NOT fonksiyonu, bir lojik işlem olarak, NEG fonksiyonu, bir aritmetik işlem olarak düşünülür. Tablo.4.18. NOT ve NEG komutlarının bazı kullanım örnekleri Asembly Dili Yapılan İşlem NOT CL CL = CL’ NEG CL CL = CL’ + 1 (2‘nin tümleyeni) NEG AX AX = AX’ + 1 (2‘nin tümleyeni) NOT TEMP DS’de bulunan TEMP ile adreslenen verinin bit’leri terslenir. TEMP’le adreslenen verinin boyu TEMP’in tanımlanmasına bağlıdır. NOT PTR[BX] BYTE DS’de bulunan BX ile adreslenen 1-byte verinin bit’leri terslenir. 4.7.4.Kaydırma ve Döndürme: 62 Kaydırma (Shift) ve döndürme (Rotate) komutları, AND, OR, XOR ve NOT komutlarında olduğu gibi, ikili sayılar üzerinde, ikili bit seviyesinde işlem yapmaktadır. 4.7.4.1.Kaydırma Komutları: Kaydırma komutları, bir saklayıcı veya hafıza hücresi üzerinde işlem yapar. Bu komutlar, 2’nin katları ile çarpma (sola kaydırma) ve bölme (sağa kaydırma) işlemlerinde kullanılır.8086/8088 komut kümesi, Şekil.4.5’te görüldüğü gibi, 2 tane lojik kaydırma ve 2 tane aritmetik kaydırma olmak üzere, toplam 4 tane kaydırma komutuna sahiptir. Aritmetik sağa kaydırma komutu olan SAR’da, eğer sayı pozitif ise, sağa ‘0’ kaydırılır; eğer sayı negatif ise, sağa ‘1’ kaydırır. Bu sağa kaydırma işleminde işaret bit’i yine yine aynı konuma kopyalanacaktır.Aritmetik sağa kaydırma ile lojik sağa kaydırma, işaretli sayılarda farklılık gösterir. SAR komutu işaretli sayıyı 2’ye böler. Buna karşın SHR komutu işaretsiz sayıyı 2’ye böler. Lojik kaydırma ise sayıyı 2 ile çarpar. Eğer 1 haneden fazla kaydırma istenirse, CL saklayıcısı kaydırma sayısını tutar. SHL SAL SHR C A0 0 C A0 0 Aritmetik Sol 0 A0 C Lojik Sağ A0 C Aritmetik Sağ SAR S Lojik Sol Şekil.4.5. Kaydırma komutları Tablo.4.19, kaydırma komutlarının değişik adresleme modlarına göre bazı kullanım örneklerini göstermektedir. Tablo.4.19. Kaydırma komutlarının bazı kullanım örnekleri Asembly Dili Yapılan İşlem SHL CX Lojik olarak CX’i sola kaydır SHR AX Lojik olarak AX’i sola kaydır SAL BUFFER,CL Aritmetik olarak DS’de bulunan BUFFER’ı sola CL’de bulunan 63 sayı kadar kaydır SAR SI Aritmetik olarak SI’yı sağa kaydır 4.7.4.2.Döndürme Komutları: 8086/8088 mikroişlemcisinde yer alan 4 döndürme komutu, bir saklayıcıdaki veya hafıza hücresindeki bilgiyi, bir ucundan diğerine veya elde bayrağı üzerinden, Şekil.4.6’da görüldüğü gibi döndürmektedir. Eğer 1 haneden fazla bir döndürme işlemi istenirse, CL saklayıcısı kaydırma sayısını tutar. Tablo.4.20, döndürme komutlarının değişik adresleme modlarına göre bazı kullanım örneklerini göstermektedir. Tablo.4.20. Döndürme komutlarının bazı kullanım örnekleri Asembly Dili Yapılan İşlem ROL DI DI sola bir bit döner. RCL CL CL sola elde üzerinden 1 bit döner. ROR AH,CL AH sola elde üzerinden CL’de bulunan sayı kadar döner. RCR WORD SS’de bulunan ve BP ile adreslenen 16-bit Word sağa 1 bit döner. PTR[BP] 64 ROL RCL ROR RCR C A0 C A0 0 A0 C A0 Şekil.4.6. Döndürme komutları 4.8.Dizi Karşılaştırmaları: Daha önceden gördüğümüz gibi, 8086/8088’de yer alan dizi komutları çok güzlüdür.; çünkü, çok az komut ile programcıya, bir veri bloğunu, hafızanın bir bölümünden diğerine aktarmayı sağlar.Bu bölümde, bir hafıza bloğunu, bir veri ile karşılaştırma işlemini yapan SCAS (Dizi Tarama) komutu ile, iki hafıza bloğunu karşılaştıran CMPS (Dizi Karşılaştırma) ek dizi komutları sunulacaktır. Daha önce sunulan, MOVS, LODS, ve STOS dizi komutları gibi, SCAS ve CMPS komutları SI ve/veya DI için otomatik arttırma veya otomatik-azaltma işlemlerini seçmede yön bayrağını (D) kullanır. Ayrıca, REPNE, REPE gibi duruma bağlı tekrar öneki ile tekrar edilebilir. 4.8.1.SCAS Komutu: Dizi tarama (Scan String) komutu, AL saklayıcısı ile bir byte hafıza bloğunu veya AX saklayıcısı ile bir 16-bit hafıza bloğunu karşılaştırır. Byte karşılaştırma işleminde SCASB, kelime karşılaştırma işleminde SCASW kullanılır. Aşağıdaki verilen dizi tarama örneğinde, BLOCK adresli yerden başlayan 100 byte veri içinde 7 sayısı aranmaktadır. SCASB komutu blok içinde 7 bulana kadar veya CX sayacı sıfır oluncaya kadar devam eder. MOV DI, OFFSET BLOCK ; veri bloğuna işaret et CLD MOV CX, 100 ; otomatik arttırma ; blok uzunluğu 65 MOV AL, 7 REPNE SCASB ; blok içinde aranacak veri ; bulunana kadar karşılaştır Diğer durumda bağlı tekrar ön eki, eşit olduğu sürece tekrar (repeat while equal) REPE ekidir. Duruma bağlı tekrarlarda, dizi işlemi, durum doğru oldukça ve CX sayacı sıfır olmadığı sürece tekrar eder. Sayaç sıfır olduğunda veya durum artık doğru değil ise tekrardan çıkılır. Her bir çevrim, sayacı bir azaltır. Sayacın azalması bayrakları etkilemez, fakat bir hafıza içeriği ile AL veya AX saklayıcısını karşılaştıran SCAS komutu bayrakları etkiler. Yukarıda verilen örnekte 7 rakamın blok içinde bulunup bulunmadığını anlamak için, SCASB komutundan sonra Z bayrağına bakmak yeterlidir. Eğer Z = 1 ise, 7, blok içindedir ve DI,7 sayının bulunduğu hafıza hücresinden bir sonraki yere işaret eder. 4.8.2.CMPS Komutu: Dizi karşılaştırma (Compare String) komutu, aynı olup olmadığını bulmak için iki hafıza bloğunu karşılaştırır. Byte Karşılaştırma işleminde CMPB, keline karşılaştırma işleminde CMPW kullanılır. Karşılaştırma işleminde, ES alanında DI ile işaretli bir hafıza hücresi, DS alanındaki SI ile adreslenen bir hücresinden çıkartılır. Bu çıkarma işleminden ne hafıza, ne saklayıcılar ne de bayraklar etkilenir. CMPS komutu, otomatik olarak SI ve DI saklayıcılarını arttırır veya azaltır. Bu komut normalde REPE veya REPNE ön eki ile beraber kullanılır. Aşağıda verilen örnek, 50 byte uzunluğunda iki hafıza bloklarının birbirlerine eşitlik olup olmadığını bulmak için, blokları karşılaştırmaktadır. CMPB komutu REPE ön eki ile kullanılmaktadır. Bu ek eşitlik durumu olduğu sürece araştırmanın devam etmesini sağlar Cx saklayıcısı 0 olduğunda veya eşit olmayan bir durumda, CMPB komutu yürütmesini durdurur. Eğer CX sıfır ise veya bayraklar eşit durum belirtir. İse, iki hafıza dizisi birbirine eşittir. MOV SI, OFFSET BLOCK1 ; veri bloğuna işaret et MOV DI, OFFSET BLOCK2 ; veri bloğuna işaret et CLD MOV CX, 50 REPE CMPSB ; otomatik arttırma ; blok uzunluğu ; dizileri karşılaştır 66 4.9.Program Kontrol Komutları: 4.9.1.Dallanma Komutları: Temel program kontrol komutu olan JMP (Jump), hafızanın bir bölümünden diğer bir bölümüne program akışını yönlendirir. Duruma bağlı dallanma komutları, bayrak bit’lerinin durumuna göre, yani bir durum testi sonucu program akışını değiştirir. 4.9.1.1.Doğrudan Dallanmalar: JMP komutunun 3 değişik şekli vardır. Bunlar: Kısa (short) dallanma, yakın (near) dallanma ve uzak (far) dallanmadır. Şekil.4.7, dallanma komutlarını, hafızadaki yer alış yapılarını ve uzunluklarını göstermektedir. (a) JMP KISA_ADR İşlem Kodu (EBH) (b) Segment içi dallanma JMP YAKIN_ADR İşlem Kodu (E9H) (c) Değişim (DISP) Değişim Düşük (DISP Low) JMP UZAK_ADR İşlem Kodu (EAH) IP Düşük (IP Low) Değişim Yüksek (DISP High) Bir segment’ten diğer bir segment’e dallanma (Segment arası dallanma) IP Yüksek (IP High) CS Düşük (CS Low) CS Yüksek (CS High) Şekil.4.7.Dallanma komutları: (a) kısa dallanma (2 byte), (b) yakın dallanma (3 byte) ve (c) uzak dallanma (5byte) 4.9.1.2.Kısa Dallanma: Kısa dallanma, 2-byte bir komuttur ve işlem kodundan sonraki ikinci byte, işaretli adres bilgisidir. Bu komut, kendisini takip eden hafıza adresinden itibaren, +127 ile –128 byte arasında bir hafıza hücresinde dallanmayı sağlar. Kısa dallanmalar, göreceli (relative) dallanmalar olarak adlandırılır. Çünkü, bu komutlar hafızada herhangi bir yere, bir değişiklik yapılmadan taşınabilir. Bu dallanma komutun içinde, işlem kodundan sonra, bir adres olmayıp yer değişim (displacement) bulunur. 4.9.1.3.Yakın Dallanma: Kısa dallanmaya benzeyen yakın dallanma 3-byte bir komuttur ve o anki CS içinde herhangi bir adrese dallanmayı sağlar. Ofset adresi 16-bit’tir. 67 4.9.1.4.Uzak Dallanma: Uzak dallanma, mikroişlemcinin hafıza adres alanındaki herhangi bir adrese dallanmayı sağlar. Kısa ve yakın dallanmalar genellikle, segment içi dallanma (intrasegment jump), uzak dallanma ise segment arası dallanma (intersegment jump) olarak adlandırılır. Programcı, dallanmalarda, JMP komutundan sonra bir adres etiketi (label) kullanır. Kullanılan assembler, dallanmanın uzunluğuna göre işlem kodu ve adres üretir. Bu yüzden programcı için yapılacak tek şey JMP’den sonra dallanılacak yerin adresini yazmaktır. 4.9.1.5.Saklayıcı Operandlı Dallanma: Dallanma komutu, bir 16-bit saklayıcı operand olarak belirlemede kullanılabilir. Bu tür dallanma, dolaylı dallanmadır ve saklayıcının içindeki adres dallanma adresi olarak kullanılır. Saklayıcının adresi IP olarak alınır ve program bu adresten itibaren devam eder. Bu çeşit bir dallanma, bir dallanma tablosu kullanmada çok yararlıdır. Aşağıda, TABLO adresinden başlayan bir dallanma tablosunda bulunan 4 farklı altprogram adresine erişen bir örnek verilmektedir. Altprogram adresleri 16-bit olduğu için bu adresler, TABLO başlangıç adresinden itibaren TABLO+0, TABLO+2, TABLO+4 be TABLO+6 adreslerinde yer almaktadır. Program başında, SI’da 0,1,2 veya 3 olduğu varsayılmakta ve iki katı alınmaktadır. Daha sonra, TABLO taban adresiyle bu adres toplanarak dallanılacak altprogram adresi bulunur. JMP AX ile bu adrese dallanır. ; Dallanma tablosu örneği ADD SI, SI ; SI’nın iki katı ADD SI, OFFSET TABLO ; alt program adresi MOV AX, CS:[SI] JMP AX ; adresi AX’e al ; alt programa dallan ... TABLO: DW SUB0 ; 4 alt program adres tablosu DW SUB1 DW SUB2 DW SUB3 68 4.9.1.6.İndisli Adresleme Kullanan Dolaylı Dallanma: Dallanma komutu indisli adresleme kullanarak bir dallanma tablosuna erişebilir. Dallanma tablosu, yakın (near) dolaylı dallanma, ofset adresleri ve uzak (far) dolaylı dallanma segment ve ofset adresleri içerir. Daha önce verilen programın aşağıda indisli adresleme kullanan şekli verilmiştir. ; Dallanma tablosu örneği ADD SI, SI ; SI’nın iki katı ADD SI, OFFSET TABLO ; alt program adresi MOV CS:[SI] ; alt programa dallan ... TABLO: DW SUB0 ; 4 alt program adres tablosu DW SUB1 DW SUB2 DW SUB3 Yukarıda verilen programda, dallanma tablosuna erişim, normal hafızaya erişim gibidir. JMP CS:[SI] komutu CS hafızada bulunan ve SI ile adreslenen hücreye işaret eder. Program akışı bu hafıza adresinde saklı olan adreste yer alan adrese dallanır. Saklayıcı ve indisli adreslemeli dallanma komutunun her ikisi de yakın dallanmadır. Yani bu dallanmalarda 16-bit ofset (IP) kullanılır ve dallanma segment içidir. Eğer, segment arası dallanma yapılmak isteniyor ise, FAR PTR eki kullanılır. Örneğin, JMP FAR PTR [SI] komutunda, mikroişlemci SI ile işaretli hafıza bölgesinde 32-bit adres (IP ve CS) varsayar. 4.9.1.7.Duruma Bağlı Dallanmalar: 8086/8088 mikroişlemcisinde duruma bağlı dallanmalar kısa dallanmadır. Yani, dallanmalar daima bir sonraki komuttan sonra +127 ile –128 byte arasındadır. Duruma bağlı dallanma komutları tablo.4.21’de test durumları ile verilmiştir. 69 Tablo.4.21. Duruma bağlı dallanma komutları Komut Test Durumu Açıklama JA C = 0 ve Z = 0 Yukarı ise dallan JAE C=0 Yukarı ya da eşit ise dallan JB C=1 Aşağı ise dallan JBE C = 1 ya da Z = 1 Aşağı ya da eşit ise dallan JC C=1 Elde 1 ise dallan JE ya da JZ Z=1 Eşit ya da sıfır ise dallan JG Z = 0 ve S = 0 Büyük ise dallan JGE S=0 Büyük ya da eşit ise dallan JL S≠0 Küçük ise dallan JLE Z = 1 ve S ≠ 0 Küçük ya da eşit ise dallan JNC C=0 Elde 0 ise dallan JNE ya da JNZ Z=0 Eşit değil ya da sıfır değil ise dallan JNO O = 0 ve Z = 0 Taşma yok ise dallan JNS S=0 S = 0 ise dallan JNP/JPO P = 0 (parity) Eşlik yok ise / eşlik tek ise dallan JO O=1 Taşma var ise dallan JP/JPE P=1 Eşlik var ise / eşlik çift ise dallan JS S=1 İşaret S = 1 ise dallan 70 JCXZ CX = 0 CX = 0 ise dallan Duruma bağlı dallanmalar şu bayrak bit’lerini test eder. İşaret (S), sıfır (Z), elde (C), eşlik (P) ve taşma (O). Eğer test edilen durum doğru ise, program akışı dallanma komutuyla belirtilen adresten devam eder. Eğer durum yanlış ise, dallanma olmaz ve bir sonraki sıradaki komut yürütülür. İşaretli sayıların karşılaştırılmasında, JG, JGE, JE, JNE, JL, JLE komutları kullanılır. İşaretsiz sayılarda ise JA, JAE, JB, JBE, JE, JNE komutları kullanılır.Tablo.4.21’de görüldüğü gibi bazı komutlar alternatif komutlara sahiptir. Örneğin, JE alternatif JZ komutuna sahiptir. Alternatif komutların çoğu programlarda kullanılmaz, çünkü bir anlam ifade etmezler. JCXZ komutu bayrakları test etmeyip CX saklayıcısının içeriğini ele alır. Eğer CX = 0 ise dallanma gerçekleşir, aksi durumda sıradaki komut yürütülür. Bu komut SCAS komutuyla yapılan bir dizi tarama işleminden sonra CX saklayıcısının durumuna göre dallanmada kullanılabilir. Aşağıda daha önce verilen örneğin sonuna JCXZ komutu eklenmiştir. Bu örnekte, 100 byte uzunluğunda bir hafıza bloğu içinde 7 sayısı aranmaktadır. Çevrim sonunda 7 bulunabilir veya bulunmayabilir. JCXZ komutu bu durumun testi için çok yararlıdır. Eğer bütün tablo aranmış ve 7 bulunmamış ise CX sıfır olur, aksi halde sıfır değildir. MOV DI, OFFSET BLOCK ; veri bloğuna işaret et CLD ; otomatik arttırma MOV CX, 100 MOV AL, 7 ; blok uzunluğu ; blok içinde arttırılacak veri REPNE SCASB ; bulunan kadar karşılaştır JCXZ BULUNMADI ... ; bulundu ise 4.10.LOOP Komutu: LOOP komutu CX saklayıcısının azaltma ile duruma bağlı dallanma işlemlerinin birleşimidir. Bu komut CX saklayıcısını bir azaltır ve eğer CX≠0, komut ile belirtilen adrese dallanır. CX sıfır olduğunda bir sonraki komut yürütülür. Aşağıda verilen örnekte, BLOCK1 ve BLOCK2 adresli yerden başlayan, 100 kelime uzunluğunda iki dizinin toplanmasında LOOP komutu kullanılmıştır. LODSW komutu BLOCK1 71 verisine ve STOSW komutu ise BLOCK2 verisine erişmektedir. ADD AX, ES:[DI] komutu ES alanında bulunan BLOCK2 verisine erişmektedir. BLOCK2’nin ES alanında olmasının tek nedeni, STOSW komutundaki DI saklayıcısının ES alanındaki veriyi adreslemiş olmasıdır. MOV SI, OFFSET BLOCK1 ; veri bloğuna işaret et MOV DI, OFFSET BLOCK2 ; veri bloğuna işaret et MOV CX, 100 MOV AL, 7 ; blok uzunluğu ; blok içinde arttırılacak veri TEKRAR: LODSW ADD AX,ES:[DI] STOSW LOOP TEKRAR ; BLOCK1 verisi oku ; BLOCK2 verisi ile topla ; BLOCK2 alanında sakla ; 100 kere tekrar et 4.10.1.Duruma Bağlı LOOP Komutları: LOOP komutu durma bağlı olabilir. Sık olarak kullanılan iki tane duruma bağlı LOOP komutu vardır. Bunlar: LOOPE ve LOOPNE komutlarıdır. LOOPE (LOOP while Equal) eşit olduğu sürece çevrim komutu, CX sıfır değil ise ve bir eşitlik durumu olmadığı sürece, adresle belirtilen yere dallanır. CX sıfır olduğunda veya bayrak bit’leri ile bir eşitsizlik durumu belirtildiğinde çevrimden çıkar. LOOPNE (LOOP while Not Equal) eşit olmadığı sürece çevrim komutu, CX sıfır değil ise ve eşitsizlik durumu olduğu sürece, adresle belirtilen yere dallanır. CX sıfır olduğunda veya bayrak bit’leri ile bir eşitlik durumu belirtildiğinde çevrimden çıkar. 4.11.Altprogramlar: Altprogram, bilgisayar yazılım mimarisinde önemli bir yer taşır. Genelde bir görev yerine getiren komutlar kümesidir. Ve hafızada bir kere yer aldıktan sonra, bir programda birçok kere kullanılır. Bu, hafıza alanından tasarruf sağlar ve altprogramlar içeren bir programı yazmak daha az zaman aldığı için programcılığı kolaylaştırır. Altprogramın bir dezavantajı, altprogram ile ana program arasındaki parametre aktarımdaki ve altprogram çağırma (CALL) ve altprogramdan dönüş (RET) işlemlerindeki ek zaman kaybıdır. 72 Bir altprogram CALL komutu ile çağrılırken, yığın (stack) hafıza, CALL komutundan sonraki komutun adresini saklamada kullanılır. RET komutu ile, yığından okunan dönüş adresinden itibaren dönüş devam eder. Bir x86 Assembler programı kullanırken alt program yazmanın bazı kuralları bulunmaktadır. Örneğin, bir altprogram, Pascal gibi yüksek seviyeli bir dildeki gibi procedure olarak adlandırılır. Altprogram PROC yönlendiricisi (directive) ile başlar ve ENDP yönlendiricisi ile biter. Bu, bir altprogramı diğer kodlardan ayırmayı sağlar. Bu iki yönlendiriciden önce altprogramın adı yazılır. PROC yönlendiricisini, altprogramın tipini belirten NEAR (segment içi) veya FAR (segmentler arası) yönlendiricisi takip eder. Aşağıda NEAR ve FAR yönlendiricisi kullanan, iki örnek altprogram yapısı verilmiştir. ; SUB0 adında NEAR altprogram yapısı SUB0 PROC NEAR ; altprogram adı ve başlangıcı ... RET SUB0 ENDP ; altprogram sonu ; SUB1 adında NEAR altprogram yapısı SUB1 PROC NEAR ; altprogram adı ve başlangıcı ... RET SUB1 ENDP ; altprogram sonu Yukarıdaki iki altprogram arasındaki fark, assembler tarafından RET komutu için üretilen kodda bulunmaktadır. NEAR RET komutu C3H işlem kodu kullanır buna karşın FAR RET komutu ise CBH işlem kodu kullanır. Yakın RET, yığından bir 16-bit sayı çeker ve bunu alt programdan dönmek için IP saklayıcısına yerleştirir. Uzak RET ise, yığından bir 32-bit sayı çeker ve bunu altprogramdan hafızanın herhangi bir yerine dönmek için IP ve CS saklayıcılarına yerleştirir. Bir MASM (Microsoft Assembler) programında NEAR ve FAR tipini USES ifadesi takip eder. Bu USES ifadesi, istenen saklayıcıların otomatik olarak yığın hafızaya atılmasını ve alt program sonu yığından çekilmesini sağlar.Birçok program tarafından kullanılacak (global) 73 altprogramlar FAR olarak tanımlanmalıdır. Bir görev tarafından kullanılan altprogramlar, normalde NEAR olarak tanımlanır. 4.12.CALL Komutu: CALL (çağırma) komutu program akışını bir altprograma aktarır. Bu komutun JMP komutundan farkı, bir CALL komutu yürütülürken mikroişlemci tarafından otomatik olarak dönüş adresi yığında saklanır. Altprogram sonundaki RET komutuyla bu dönüş adresi yığından çekilir ve programda CALL komutundan sonraki komuta dönülmüş olur. 4.12.1.Yakın CALL: Yakın CALL komutunda, 8086-80286’da, ilk byte işlem kodundan ikinci ve üçüncü byte’lar, uzunluğu ±32K değişim adresi olup toplam 3-byte’tır. 80386 üstü işlemciler, korumalı modda çalıştıklarında, 32-bit değişim kullanılarak ±2G byte’lık bir alan sağlar. Yakın CALL daha önce gördüğümüz yakın JMP komutuna benzemektedir. Kısa CALL komutu bulunmamaktadır. 4.12.2.Uzak CALL: Uzak CALL, 5-byte uzunluğundadır ve işlem kodundan sonra dallanacak altprogramın IP ve CS adresleri komut içinde bulunur. FAR CALL komutu yürütülürken, dallanmadan önce, yığına o anki IP ve CS yerleştirilir. Bu sayede hafızanın herhangi bir yerine yerleştirilmiş bir altprogram çağrılır. 4.12.3.Saklayıcı Operand’lı CALL: JMP komutunda olduğu gibi, CALL da bir saklayıcıyı bir operand olarak kullanabilir. Örneğin, CALL BX komutunda, önce o anki IP yığına atılır. Daha sonra, BX saklayıcısındaki ofset adres, o anki kod segment’te bulunan bir altprogram çağrımı için IP adresi olarak alınır. Bu tip bir CALL komutunda, bir16-bit saklayıcıda bulunan sayı 16-bit ofset olarak kullanılır. 4.12.4.Dolaylı Hafıza Adresi Kullanan CALL: Bu tür bir altprogram çağırma, değişik altprogramları bir parametreye göre seçip çağırmada yararlıdır. Aşağıda verilen örnekte, 3 altprogramdan biri, DI’daki bir parametreye göre çağırılmaktadır. Altprogramlar, DI’daki 0,1 ve 2 sayılarına göre belirtilmektedir. Eğer, bu indisler 1’den başlasaydı, programın başında DI saklayıcısını 1 azaltmamız gerekecekti. Altprogram adresleri, TABLO adresinden itibaren 2-byte aralıklarla saklandığından, bu tabloya erişirken DI saklayıcısındaki indisin 2 katı alınır. ‘CS:’ öneki CALL komutundaki operand’ın önüne gelmektedir. Çünkü [BX+DI] ile CS alanında bulunan TABLO’ya erişilmektedir. 74 ; alt program çağırma tablosu örneği TABLO DW SUB0 ; Altprogram look-up tablosu DW SUB1 DW SUB2 ; Altprogram çağırma komutları ADD DI, DI ; DI’nın iki katı MOV BX, OFFSET TABLO ; TABLO’ya işaret et CALL CS:[BX:DI] ; Alt program çağır SUB0 PROC NEAR ... RET SUB0 ENDP SUB1 PROC NEAR ... RET SUB1 ENDP SUB2 PROC NEAR ... RET SUB2 ENDP CALL komutuyla uzak adresler uzak adreslerde kullanılabilir. Bu durumda CALL komutundan sonra FAR PTR kullanılır. Örneğin, CALL FAR PTR [SI] gibi. Bu durumda, DS alanında SI ile işaretli alandan 32-bit bir adres okunur ve bu adres FAR olarak tanımlı bir altprogram adresi olarak işlenir. 75 4.13.RET Komutu: Dönüş RET komutu, yığın hafızadaki yakın dönüş için 16-bit bir sayı veya uzak dönüş için 32-bit bir sayı çeker. Bu sayıyı IP saklayıcısına (yakın dönüşte) ve IP ve CS saklayıcılarına (uzak dönüşte) yerleştirir. NEAR ve FAR RET komutları, altprogram tamamlanmasında PROC yönlendirmesiyle belirlenir ve buna göre kullanılan assembler yakın ve uzak RET komutu için işlem kodu üretir. RET komutunun bir operand kullanan bir şekli daha vardır. Bu RET komutunda altprogramdan dönmeden önce SP içeriğine RET komutundan sonra yazılan operand eklenir. Bu işlem, yığındaki verinin geçilmesi veya silinmesi anlamına gelir. Örneğin, aşağıda verilen kod örneğindeki altprograma girildikten sonraki iki PUSH işlemiyle yığına iki tane 16-bit sayı yazılarak yığın 4 byte büyümüştür. RET 4 komutu, SP’ye 4 ekleyerek bu 4 byte’ın atılmasına neden olur. Bu şekilde RET komutuyla, bu altprogramı çağıran CALL komutundan sonraki satıra doğru olarak dönmüş oluruz. TEST PROC NEAR PUSH AX PUSH BX ... RET 4 TEST ENDP Eğer, bir altprogramda yapılan PUSH ve POP’ların sayısı birbirine eşit değil ise, bu şekilde bir RET komutu kullanılabilir. Yığın hafızanın, RET komutundan önce, düzgün olarak bırakılması, yani yığının en üstünde dönüş adresinin olması gerekmektedir. Aksi durumda, altprogramdan dönüş istenmeyen bir hafıza adresine olur. 4.14.Kesmelere Giriş: Kesme, bir donanım (bir harici donanım sinyalinden) veya yazılımın ürettiği bir CALL (bir komut ile dahili olarak üretilen) işlemidir. Her iki durumda da bir kesme hizmet programı (Interrupt Service Routine - ISR) çağrılır. Bu bölümde, CALL komutunun özel çeşitleri olan yazılım kesmeleri sunulacaktır. Yazılım kesmelerinde üçü (INT, INTO ve INT 3) tanıtılacak, kesme vektörleri anlatılacak ve özel kesme dönüş komutu IRET’in çalıştırılması açıklanacaktır. 76 4.14.1.Kesme Vektörleri: Kesme vektörü, mikroişlemci gerçek modda çalışırken, hafızanın ilk 1024 byte’lık alanında (003FFH-00000H) saklı olan 4-byte bir adrestir. Her bir kesme vektörü, bir kesme hizmet programının adresini oluşturan bir IP ve CS içerir. İlk 2 byte IP ve son 2 byte CS adresidir. 256 tane farklı kesme vektörü bulunur. Her vektör, kesme ile çağrıları bir kesme hizmet programının adresini tutar. Tablo.4.22, açıklamalarıyla beraber, kesme vektörlerini ve gerçek modda her vektöre karşı gelen adresleri göstermektedir. Intel ilk 32 kesme vektörünü (0-31) 8086-80486 ve gelecek ürünler için ayırmaktadır. Geri kalan kesme vektörleri (32-255) kullanıcı içindir. Ayrılı vektörlerden bazıları, bölme hatası gibi, program yürütme sırasında oluşan hatalar içindir. Bazıları yardımcı işlemci için ayrılmıştır. Diğerleri sistemdeki diğer durumlar ve korumalı modda çalışmada oluşan hatalar içindir. Korumalı modda kesme vektör tablosu yerine, daha önce gördüğümüz gibi, her kesme için 8-byte içeren, kesme tanımlayıcı (descriptor) tablosu yer alır. 4.14.2.Kesme Komutları: 8086-80486 üç farklı kesme komutuna sahiptir. INT, INTO ve INT3. Gerçek modda, bu komutlardan her biri, vektör tablosundan bir vektör okur ve sonra bu vektörle adreslenen kesme hizmet programını çağırır. Korumalı modda bu komutlardan her biri kesme tanımlayıcı tablosundan bir kesme tanımlayıcısı okur. Bu okunan tanımlayıcı hizmet programını belirtir. Kesme çağırma, uzak CALL komutuna benzer; çünkü dönüş adresi (IP/EIP ve CS) yığına yerleştirilir. Tablo.4.22. Kesme Vektörleri Kesme no Adres Mikroişlemci İşlev 0 0H-3H Bütün Bölme hatası 1 4H-7H Bütün Tek adım 2 8H-BH Bütün NMI 3 CH-FH Bütün Durma noktası 4 10H-13H Bütün Taşma kesmesi 5 14H-17H 80186-Pentium BOUND kesmesi 77 6 18H-1BH 80186-Pentium Geçersiz işlem kodu 7 1CH-1FH 80186-Pentium Yardımcı işlemci (emulation) kesmesi 8 20H-23H 80386-Pentium Çift hatası (Double fault) 9 24H-27H 80386 Yardımcı işlemci segment overrun 10 28H-2BH 80386-Pentium Geçersiz durum segment’i 11 2CH-2FH 80386-Pentium Segment mevcut değil 12 30H-33H 80386-Pentium Yığın hatası 13 34H-37H 80386-Pentium Genel koruma hatası 14 38H-3BH 80386-Pentium Sayfa hatası 15 3CH-3FH ---- Ayrılmış* 16 40H-43H 80286-Pentium Kayan-nokta hatası 17 44H-47H 80486SX Ayarlama (alignment) kontrol kesmesi 18 48H-4FH Pentium Makine kontrol 19-31 50H-7HH ---- Ayrılmış* 32-255 80H-3FFH Bütün Kullanıcı kesmeleri 4.14.2.1.INT: Programcının kullanabileceği 256 tane farklı yazılım kesme komutu (INT) bulunmaktadır. Her INT komutu, 2-byte uzunluğunda olup değeri 0 ile 255 (FFH-00H) arasında değişen bir 78 nümerik operand’a sahiptir. İlk byte işlem kodu, ikinci byte vektör tipi numarasıdır. Yalnızca yazılım kesmesi INT3 farklılık gösterir ve bu komut 1-byte uzunluğundadır. INT komutu ile yapılan işlem, FAR CALL komutu ile yapılana benzemektedir. INT komutu 2 byte olmasına karşın FAR CALL 5 byte uzunluğundadır. CALL yerine INT komutunun kullanılması, INT komutunun çok kullanıldığı programlarda, önemli bir hafıza tasarrufu sağlar.Kesme vektörünün adresini hesaplarken, kesme tipi numarası 4 ile çarpılır. Örneğin, INT 10H komutu, gerçek modda, adresi hafızanın 40H hücresinde saklı olan bir kesme hizmet programını çağırır. Korumalı modda ise, bu sayı 4 yerine 8 ile çarpılır. Çünkü her kesme tanımlayıcısı 8-byte uzunluğundadır. Bir yazılım kesmesi yürütüldüğünde: • Bayrak saklayıcısı yığına atılır. • T ve I bayrakları temizlenir. • CS yığına atılır ve CS için vektörlerden yeni bir değer okunur. • IP/EIP yığına atılır ve IP/EIP için vektörden yeni bir değer okunur. • Yeni CS:IP/EIP ile adreslenen yere dallanır. INT komutu yürütüldüğünde, harici donanım kesme giriş ucu INTR’i (Interrupt Request) kontrol eden kesme bayrağı (I) temizlenir. I = 0 olduğunda mikroişlemci INTR ucunu pasifler (disabled), yani bu uçtan gelecek kesmelere cevap vermez. I bayrağı yeniden 1 olduğunda bu kesme giriş ucu aktif duruma gelir. Yazılım kesmeleri, genellikle sistem programları çağırmada kullanılır. Sistem programları, bütün sistem ve uygulama programları tarafından kullanılabilen programlardır. Örneğin, IBM PC’de yazılım kesmeleri, yazıcıları, video birimlerini ve disk sürücüleri gibi donanım birimlerini kontrol etmede kullanılır. 4.14.2.2.IRET/IRETD: IRET komutu gerçek modda, IRETD komutu ise korumalı modda kullanılır. Kesme dönüş komutu IRET yalnız yazılım veya donanım kesme hizmet programlarında kullanılır. Basit dönüş RET komutundan farklı olarak, IRET komutu, yığından IP ve CS olarak alınacak 2 tane 16-bit veri çektikten sonra bayrak saklayıcısına bir 16-bit veri yığından okur. IRET komutu yürütüldüğünden, I ve T eski değerlerine döner. 80286-80486 mikroişlemcilerinde, korumalı modda çağrılmış bir kesme hizmet programından dönüş için IRET komutu kullanılır. IRET komutu komutundan farklı olarak, yığın hafızadan 32-bit IP (EIP) çekilir. 79 4.14.2.3.INT3: Özel bir yazılım kesmesi olan INT3, programlarda durma noktası (break point) oluşturmada kullanılır ve uzunluğu 1-byte’tır. Genellikle program hatalarını bulurken program akışını kırmada ve kesmede kullanılır. 4.14.2.4.INTO: Taşıma durumunda oluşan bu kesme, taşıma bayrağını (O) test eden duruma bağlı bir yazılım kesmesidir. Eğer O=0 ise INTO komutu bir işleme neden olmaz, fakat O=1 ise ve INTO komutu yürütülmüş ise, vektör tip numarası 4 olan bir kesme oluşur. INTO komutu işaretli ikili sayıları toplayan veya çıkaran program işaretli iki sayıyı toplayan veya çıkaran programlarda kullanılır. JO veya INTO komutu bir taşma durumunu bulmak için kullanılabilir. 4.14.2.5.Kesme Hizmet Programı: Bir kesme kesme altprogramının tanımlanması daha önce verilen, bir alt program yazma işlemi gibidir. Tek fark, altprogramda kullanılan RET komutunun yerine, kesme hizmet programında IRET komutunun kullanılması ve bu kesme alt programının adresinin, programın başında ilk işlemler yapılırken, kesme tablosunda yerleştirilmesidir. Aşağıda bir kesme hizmet programının genel çerçevesi verilmiştir. INTS PROC FAR ... RET 4 INTS ENDP 4.14.2.6.Kesme Kontrol: INTR donanım kesmesini kontrol eden iki komut bulunmaktadır. STI (Set Interrupt flag) komutu I bayrağını 1’lemekte ve bu da INTR girişini aktif duruma getirmektedir. CLI (CLear Interrupt flag) komutu I bayrağını 0’lamakta ve bu da INTR girişini pasif yapmaktadır. Bir yazılım kesme hizmet programı içinde, ilk adım olarak, genellikle donanım kesmeleri STI komutu kullanılarak aktif yapılır. 80 4.14.2.7.İşlemci Kontrol ve Diğer Komutlar: 8086-80486 komut kümesindeki son grup, işlemci kontrol komutları ile şimdiye kadar olan gruplara girmeyen diğer komutlardır. Bu komutlar elde bayrağını kontol, BUSY / TEST ucunu örnekleme, mikroişlemciyi durdurma gibi fonksiyonlar sağlar. 4.14.2.8.Elde Bayrağını Kontrol: Elde bayrağını uzun Word toplama ve çıkarma işlemlerinde kullanılır. Ayrıca, bir altprogramdan dönerken, bir hata durumu veya başka bir durum, 1 veya 0 ile çağrılan program bildirmede boolean bayrak olarak ta kullanılır. Elde bayrağını (C) kontrol etmeye yönelik 3 tane komut bulunmaktadır. Bu komutlar: elde bayrağını 1’le, STC (Set Carry); elde bayrağını temizle, CLC (Clear Carry); elde bayrağının tersini al, CMC (Complement Carry). 4.14.2.9.WAIT: WAIT komutu 80286-80386’da BUSY donanım ucunu, 8086/8088’de ise TEST ucunu gözler. Bu ucun adı 80286 işlemcisinden itibaren TEST’ten BUSY’ye değişti. WAIT komutu yürütüldüğünde, bu uç 0 ise, bir şey olmaz ve bir sonraki komut yürütülür. Eğer bu uç 1 ve WAIT komutu yürütülmüş ise, mikroişlemci bu ucun lojik 0 seviyesinde dönmesini bekler. IBM PC’de, mikroişlemcinin BUSY ucu, genellikle 8087-87387gibi nümerik yardımcı işlemcinin BUSY ucuna bağlanır. Bu bağlantı ve WAIT komutu, yardımcı işlemci görevini bitirene kadar, 808680386 işlemcisinin beklemesini sağlar. 4.14.2.10.HLT: HLT komutu program yürütmesini durdurur. Bir durma işleminde çıkmak için 3 yol vardır: bir kesme ile, bir donanım kesmesi veya bir DMA işlemi sırasında. Bu komut, normalde bir kesmeyi beklemek amacıyla kullanılır. Harici donanım kesmeleri ile yazılım sistemini senkronize etmeye de yararlıdır. 4.14.2.11.NOP: Mikroişlemci NOP (No Operation ) komutuna rastladığı zaman, bir işlem yapmayıp sadece çok kısa bir zaman harcar. Bu zaman, bu komutun hafızadan okunma (fetch) süresidir. Program geliştirilirken, bu komut ileride başka komutlarla değiştirilmek üzere, program aralarında çeşitli yerlere konulabilir. Bu sayede NOP konulduğu yerler, programcıya eklerin yapılacağı 81 önemli noktaları hatırlatır. NOP komutu aracılığıyla, yazılım gecikmeleri sağlamak amacıyla sık olarak kullanılır. 4.14.2.12.LOCK Ön Eki: LOCK ön eki bir komuta ilave edildiği zaman LOCK donanım ucu lojik 0 olur. bu uç genellikle harici yol işlemlerini düzenleyici tüm devreleri (bus masters) ve diğer sistem birimlerini pasif duruma getirir. LOCK ön eki bir ya da sıralı birden fazla komutun önünde olduğunda, bu komut ya da komutlar kilitli durumda olur. bu komutların yürütülmesi sırasında, LOCK ucu lojik 0 seviyesinde kalır. Örneğin, LOCCCCKKK komutu kilitli bir komuta örnektir. 4.14.2.13.ESC: ESC (Escape) komutu, 8087-80387 nümerik işlemcisine mikroişlemciden bilgi aktarmada kullanılır. ESC komutu yürütüldüğünde, mikroişlemci, istenirse, bir hafıza adresi sağlar, aksi durumda, bir NOP işlemi yapar. 82 5.BÖLÜM 5.ASSEMBLER DİREKTİFLERİ 5.1.Data Direktifleri 5.1.1. Sembol Tanımlama EQU :Bir yazı veya matematiksel ifadeyi bir isme kalıcı olarak atar. Biçim : isim EQU yazı İsim EQU matematiksel ifade = : matematiksel bir ifadeyi bir isme atar,fakat isme yeni bir değer atanabilir. Biçim : isim=matematiksel_ifade Data direktiflerinde atanan ifade,16 bitlik bir sabit,adres,başka bir sembolik isim veya saklayıcı ismi olabilir. Örnek.5.1.: K EQU 247 TABLO EQU DS : [BP] [SI] HIZ EQU ORAN SAYI EQU CX MAX.HIZ EQU 2*HIZ SABİT = 56 SABİT = SABİT + 1 5.1.2. Data Tanımlama DB : Değişken tanımlar veya değişkene ilk değer atar. DB, hafızada 1byte yer ayırır. Biçim : [isim] DB ifade [,…] DW : DB ile aynı fakat hafızada 2 byte’lık yer ayırır. DD : DB ile aynı fakat hafızada 4 byte’lık yer ayırır. Pek çok program, değişkenleri saklamak için hafızada yer ayırır. DB (Define Byte) Byte tanımla,DW (Define Word) word tanımla, DD (Define Double Word), iki word tanımla direktifleri değişkenler için hafızada yer ayırır. Data tanımlama direktiflerinin genel biçimi: [isim] DB ifade [,….] 83 [isim] DW ifade [,….] [isim] DD ifade [,….] şeklindedir. Burada kullanılan ifade değişkenleri nasıl tanımlamak istediğinize bağlı olarak farklı şekillerde olabilir. Örnek.5.2: (sabit olabilir) MAX_SAYI DB 255 MAX_SAYI DW 65535 MAX_ISARETLI_SAYI DB -128 MAX_ISARETLI_SAYI_1 DW -32768 Örnek.5.3 : (tablo olabilir) B_TABLO DB 0, 0, 0, 0, 1, 123, 46, -56 W_TABLO DW 1025, 567, -3100, 300 B1_TABLO DB 4 DUP(0), 1, 123, 46, -56 -Eğer değişkene bir başlangıç değeri vermek istemiyorsak (?) kullanabiliriz. Örnek.5.4 : MAX_SICAKLIK DB ? MAX_HIZ DW ? AYLIK_SATIS DB 30 DUP (?) -DB direktifi karakter katarını (string) bir ifade olarak kabul eder. Örnek.5.5 : MESAJ DB ‘BIR SAYI GIRIN’ 5.1.3. Segment - Prosedür Tanımlama : 5.1.3.1.Segment:Segmentin sınırlarını tamınlar.Bütün segment tanımlamaları ENDS ile bitmelidir.SEGMENT ve ENDS direktifleri kaynak programları segmentlere ayırır. Bir program dört çeşit segmente (data, kod, ekstra , yığın) ayrılabilir. SEGMENT saklayıcısının 3 adet operantı vardır. Bunlar; Yerleştirme Tipi (Align Type), Birleştirme Tipi (Combine Type) ve sınıf (Class) dır. 84 Biçim : segment_ismi [Birleştirme Tipi] SEGMENT [Yerleştirme_Tipi] (align_type) (combine_type) [Sınıf] (class) …. ..…. segment_ismi ENDS Yerleştirme tipi : Segment hafızaya yüklendiğinde başlangıç sınır değerini belirtir. BYTE : segmentin hafızada herhangi bir yerden başlayabileceğini belirtir. WORD : segmentin hafızada çift adres değerinden başlayabileceğini belirtir. PARA: segmentin hafızada 16 ya bölünebilen adres değerinden başlayabileceğini belirtir. PAGE : segmentin hafızada 256 ya bölünebilen adres değerinden başlayabileceğini belirtir. Birleşme Tipi: Segmentin diğer egmentlere nasıl birleştirileeğini gösterir. Data ve extra segmentler PUBLIC veya COMMON olabilir. PUBLIC : segmentlerin üst üste birleşebileceğini söyler. COMMON : segmentlerin içiçe yerleştirileceğini söyler. STACK : Yığın Segmenti (SS) mutlaka STACK tipinde olmalıdır. Sınıf Tipi : Hafızaya yüklenecek segmentin sırasını beliritir. Aynı sınıf ismine sahip olan segmentler hafızaya birbiri ardına yüklenirken, farklı sınıf ismine sahip olan segmentlerin hafızaya üklenme biçimini linker düzenler. Örnek.5.6: Data Segment Kod Segment : SEGMENT PARA PUBLIC ‘DATA’ : SEGMENT PARA PUBLIC ‘CODE’ Ekstra Segment : SEGMENT PARA PUBLIC ‘EXTRA’ Yığın Segment : SEGMENT PARA PUBLIC ‘STACK’ Örnek.5.7: Bir data segmentin yapısı DSEG SEGMENT PARA PUBLIC ‘DATA’ A B DB ? DB KARE DB 1,2,4,,8,16,32 85 DSEG ENDS Örnek.5.8: Bir kod segmentin yapısı CSEG SEGMENT PARA PUBLIC ‘CODE’ CSEG ENDS ASSUME SEGMENT ve ENDS direktifleri bir segmentin başlangıç ve sonunu belirtir. Fakat segmentin ne tür bir segment olduğunu belirtmez. Segmentin ne tür bir segment olduğunu belirtmek için ASSUME direktifi kullanılır. ASSUME , Assembler’a hangi segmentin hangi hangi segment saklayıcısına (CS,DS,ES) ait olduğunu söyler. NOTHING direktifi daha önce tanımlanmış ASSUME direktifini iptal eder. Biçim : ASSUME seg_reg :segment_ismi [,….] Seg_reg ; CS,DS,ES,SS olabilir Segment_ismi ; SEGMENT direktifi ile tanımlanan isimdir. ASSUME direktifi, Assembler’in tanımlanan etiketleri adres değerine dönüştürmesini sağlar.ASSUME direktifi, kod segmetle SEGMENT tanımlanmasından hemen sonra tanımlanmalıdır. Örnek.5.9: CSEG SEGMENT PARA PUBLIC ‘CODE’ ASSUME CS:CSEG, DS:DSEG MOV AX, DESG MOV DS, AX NOT:Data ve Extra segment adreslerini saklayıcıları ayrıca atamak gerekir. ASSUME komutu bu işlemi yapmaz. PROC : Assembler’a bir prosedür tanımlandığını belirtir. Bütün PROC tanımlamaları mutlaka ENDP direktifi ile bitmelidir. Biçim :isim PROC [NEAR] veya isim PROC [FAR] ….. 86 . RET isim ENDP Bir prosedürün iki operandı vardır. Bunlar NEAR ve FAR ‘dır. Eğer bu operand yazılmazsa, macroassembler bunu NEAR sayar. NEAR olarak tanımlanmış prosedürler sadece tanımlandıkları kod segment saklayıcısı içine çağırılabilir. Örnek.5.10 : CSEG SEGMENT PARA PUBLIC ‘CODE’ ASSUME CS:CSEG ANA PROC FAR .... CALL ALT_1 RET ANA ENDP ALT_1 PROC NEAR ..... RET ALT_1 CSEG ENDP ENDS FAR olarak tanımlanmış prosedürler başka bir kod segment içinden çağırılabilir. Örnek.5.11: CSEG SEGMENT PARA PUBLIC ‘CODE’ ASSUME CS:CSEG1 ALT1 RROC FAR ...... .... . 87 RET ALT_1 ENDP C SEG_1 ENDS Mikroişlemci bir prosedürü çağırdığında, geri dönüş adresini yığına atar. Eğer prosedür FAR olarak tanımlanmışsa yığına segment ve offset (CS:IP) adres değerleri atanır. Eğer prosedür NEAR olarak tanımlanmışsa yığına sadece offset (IP) adres değeri atanır. RET komutunda ise yığına atılan bu adres değerleri (prosedürün NEAR veya FAR olarak tanımlandığına bağlı olarak ) CS=IP ye geri yüklenir. Bir prosedürün operandları tanımlanırken aşağıdaki kurallar hatırlanmalıdır. 1-) .EXE türü programlar için ana prosedür FAR olmalıdır. .COM türü programlar için NEAR olmalıdır. 2-) Eğer bütün kod segmentlerin ismi aynı ise bütün prosedürler , (ana prosedür haricinde) NEAR olmalıdır. 5.1.4. Assembler Kontrol : END Biçim : : Kaynak programın sonunu gösterir. END [Program_başlangıç_noktası] EVEN Biçim : ORG : Programın başlangıcının adresinin çift değerde olmasını sağlar. EVEN : İfadenin başlangıç değerinin gösterir. ORG direktifi, komut veya ifadenin hafızada belli bir yerde saklanmasını sağlar. Çoğunlukla .COM tipi programlarda kullanılır. Biçim : Örnek.5.12: ORG ifade ORG 100H END direktifi programın sonunu gösterir. Bundan dolayı her programın sonunda mutlaka END direktifi bulunmalıdır. Buradaki başlangıç noktası adrestir. Biçim: END Başlangıç 88 DOS’un programı çalıştırmaya başladığı 5.2. Mode Direktifleri Macro Assembler, Intel 80x86 ailesi işlemcilerinde kullanılmak amacıyla tasarlanmıştır. Intel 80x86 işelmcileri birbirleri ile geriye doğru uyumludurlar fakat 8086 dan sonra her yeni işlemcide yeni komutlar eklenmiştir.Eğer Macro Assembler programında 8086komut kümesinden farklı istemcinin (Örnek 80286, 80386…) komut kümesi kullanılmışsa, bu programın ilk başında tanımlanmalıdır. Örnek.5.13: .8086 .80286 : Tanımlamaya gerek yok : 80286 gerçek mod .80286 P : 80286 korunmuş mod. .8087 : 8087 matematik işlemci 5.3. Operatörler Operatörler, operand alanında ve operantı değiştirmek amacıyla kullanılır. 5 çeşit operatör vardır. Bunlar matematiksel,mantıksal,ilişkisel, değer geri döndüren ve öznitelik operatörleridir. Kısaca tablo halinde aşağıda verilmiştir. 5.3.1. Matematiksel : + Biçim Deger 1 + Deger 2 (Deger 1 ve Deger 2’yi toplar.) - Biçim Deger 1 - Deger 2 (Deger 1 den Deger 2’yi çıkarır.) * Biçim Deger 1 * Deger 2 (Deger 1 ile Deger 2 çarpılır.) / MOD Biçim Deger 1 / Deger 2 (Deger 1’i Deger 2’ye böler; bölüm değerini verir.) Biçim Deger 1 MOD Deger 2 (Deger 1’i Deger 2’ye böler. Kalan değerini verir.) SHL Biçim Deger 1 SHL Deger 2 (Değeri, belirtilen ifade kadar bit pozisyonunda sola kaydırır.) SHR Biçim Deger 1 SHR pozisyonunda sağa kaydırır.) 89 Deger 2 (Değeri, belirtilen ifade kadar bit 5.3.2. Mantıksal : AND Biçim Deger 1 AND Deger 2 (Deger 1 ve Deger 2 arasında mantıksal AND Biçim Deger 1 OR Deger 2 (Deger 1 ve Deger 2 arasında Biçim Deger 1 XOR Deger 2 (Deger 1 ve Deger 2 arasında mantıksal XOR işlemi yapar.) OR mantıksal OR işlemi yapar.) XOR işlemi yapar.) NOT Biçim NOT Deger (Deger’in 1’e göre değilini alır.) 5.3.3. İlişkisel : EQ Biçim operand 1 EQ operand 2 (Her iki operand birbirine eşit ise doğru.) NE Biçim operand 1 NE operand 2 (Her iki operand birbirine eşit ise doğru.) LT Biçim operand 1 LT operand 2 (Operand 1 operand 2’den küçük ise doğru.) GT Biçim operand 1 GT operand 2 (Operan 1 operand 2’den büyük ise doğru.) GE Biçim operand 1 GE operand 2 (Operand 1,operand 2’den büyük veya eşit ise doğru.) LE Biçim operand 1 LE operand 2 (operand 1, operand 2 ‘den küçük veya eşitse doğru.) 5.3.4. Değer Geri Döndüren : $ SEG Biçim $ (O anki adresin değerini geri döndürür.) Biçim SEG degisken veya SEG etiket (Degişken veya etiketin segment adres değerini geri döndürür.) OFFSET Biçim OFFSET degisken veya OFFSET etiket (Degisken veya etiketin offset adres değerini geri döndürür.) 5.3.5. Öznitelik : PTR Biçim Tip PTR ifade (İfadenin, daha önce tanımlanan özniteliği tip ile tanımlanan yeni özniteliğe dönüştürür. Bu öznitelikler (BYTE, WORD) gibi tip gösteren veya (NEAR, FAR) gibi mesafegösteren operandlar olabilir ) SHORT Biçim JMP SHORT etiket (Jmp koomutunun +/- 127 sınırları içinde olması sağlanır.) 90 Örnekler Matematiksel Operatörler : Bu operatörler sayısal operandları birleştirir ve sayısal yeni bir sonuç üretir. Örnek.5.14: PI EQU 22/7 MASKE EQU 110010 B MASKE_SOL_2 EQU MASK SHL 2 MASKE_SAG_2 EQU MASK SHR 2 Mantıksal Operatörler : Bu operatörler iki operand arasında mantıksal işlemler yapar. Örnek.5.15 : DEGER EQ 10111010 B DEGER EQ 00001111 B MASKE_VE_DEGER EQU DEGER AND MASKE İlişkisel Operatörler : Bu operatörler iki sayısal değeri veya aynı segmentteki hafıza değerini karşılaştırır. Sonuç eğer ilişki yanlışsa 0000H, doğru ise FFFFH olur.İlişkisel operatörler bazen diğer operatörlerle beraber kullanılır. Örnek.5.16 : SECIM EQ 18 SECIM EQ 25 MOV AX, SECIM LT 20 MOV ise assembler AX, SECIM LT 20 ise assembler MOV AX, 0FFFFH MOV AX, 0 komutunu işler Örnek.5.17 : MOV AX, ((SECIM LT 20) AND 5) OR ((SECIM GE 20) AND 6) Değer Geri Döndüren Operatorler : Bu operatorler değişkenler veya etiketler hakkındaprograma biilgi verir. Örnek.5.18 : MESAJ DB ‘Herhangi Bir Tusa Basın. ’ MESAJ_DEGER EQU $ MESAJ Örnek.5.19 : TABLO DB 100 DUP (0) MOV AX, SEG TABLO MOV BX, OFFSET TABLO 91 Özniteliksel Operatörler : Örnek.5.20 : WORD_TABLO ILK_BYTE DW 100 DUP (?) EQU BYTE PTR WORD_TABLO BESİNCİ_BYTE EQU ILK_BYTE + 4 5.4.İleri Direktifler Bu bölüm daha az genel veya ileri programcılar tarafından kullanılan ilave talimatları tanımlar. Tablo.5.1’de bu ileri talimatlar Veri, koşul, listeleme olmak üzere üç grupta listelenmiştir. Tablo.5.1. İleri Talimatlar: Tip Talimatlar Veri Grup Etiket Koşul ELSE IFNDEF IF1 ENDIF IFDEF IF2 IF IFE IFDEF IFIDN CREF %OUT LFCOND SFCOND LIST XREF Listeleme 5.4.1.Data Direktifleri: Tablo.5.2, assembler’ın ileri data direktiflerini tanımlar. Tablo.5.2. İleri Data Direktifleri: 92 %XLIST Direktif İşlev Grup Biçimi: isim GROUP seg_ismi [........] Belirtilmiş segmetleri bir isim altında toplar. Böylece bunlar 64K-byte’la fiziksel segmentte konumlanır. Etiket Biçimi: isim ETİKET tip İsmin özelliklerini tanımlar GROUP direktifi segmentlerin topluluğuna bir isim veir. Bu segmentler içindeki segment saklayıcısıyla bir ayarlamayla adreslenebilir yapar. Macro Assembler manual içinde özetlenmiş bu kuralları izlerseniz.Zaten bir 64K fiziksel segment ile saklanmış gruplanmış segmentler elde edersiniz. Örnek olması için ayrı kod ve data segmentlerde bir COM dosyası yaratarak GROUP kullanabilirsiniz. Bütün datada JMP ile bir segment’ten daha iyidir. Bir diğer uygulamada, dışsal disk dosyalarında iki prosedür kullanmak istediğiniz varsayılıyor. Sorun şu prosedürlerin her ikiside NEAR bloğu, ancak bunlar farklı isimlerdeki kod segment’ler içeriyorlar. Kendine özgü olarak PROC1 CODESEG içinde ve data DATASEG içinde, iken PROC2 CODE_SEG içinde; data DATA_SEG içinde NEAR’dan itibaren prosefürler yalnızca aynı isimle çağrılabilirler.Bu size göre şanssızlık gibi görünüyor. Kurtulmak için GROUP. Sizin programı çağırma; bu yabancı tehlikeye Örnek.5.21’deki gibi bir örnekle ulaşabilirsiniz. Örnek.5.21 : GROUP’ların örneği: ; dışsal kullanılan segmetleri tanımlar. CODESEG SEGMET PARA PUBLIC ‘CODE’ EXTRN PROC1 NEAR CODESEG ENDS CODE_SEG SEGMENT PARA PUBLIC ‘CODE’ EXTRN PROC2 NEAR CODE_SEG ENDS 93 DATASEG SEGMENT PARA PUBLIC ‘DATA’ DATASEG ENDS DATA_SEG SEGMENT PARA PUBLIC ‘DATA’ DATA_SEG ENDS ; Kod ve data gruplarını tanımlar. CGROUP GROUP CSEG, SODESEG, CODE_SEG DGROUP GROUP DATASEG, DATA_SEG ; Ana program buradan başlar. CSEG SEGMENT PARA PUBLIC ‘CODE’ ASSUME CS:GROUP, DS:DGROUP, SS:STACK ENTRY PROC NEAR ----------------- MOV AX, DGROUP ; DS noktasını GROUP yapar MOV DS, AX --------------CALL PROC1 CALL PROC2 --------------RET ENTRY ENDP CSEG ENDS END ENTRY 94 Burada, biz aptal tanımlamaları gruplanmış segmentler olması için ayarlıyoruz. Ve EXTRN’leri görünen kod segmentlerle birlikte koyuyoruz. (Bu yardımlar onları bulan bağlayıcılardır.) sonra iki grup tanımlıyoruz. GCROUP kod segmentler için, DGROUP data segmentler içindir. En sonunda çağırma programı ayarlıyoruz. Not: Bu ASSUME grup noktaları ayrı ayrı bireysel segmentlerden daha iyidir, ve biz bunu DGROUP’a DS ile yapıyoruz. MOV DX, OFFSET MESSAGE’daki gibi bu direktiflerde grup kullanmanın bir riski var. Offset kullanıldıktan beri segmentin içindeki offset, segment tutucusundaki tabandan gelmez. Çalışır yapmak için MOV DX, OFFSET CGROUP : MSG gibi blok girmelisiniz. LABEL direktifi segmenti, offset’i ve tip özelliğinin ismini tanımlar. LABEL’ı nir FAR özelliğine bir direktif vermek için kullanabilirsiniz. Böylece bu atlmama direktifi başka bir segment’i buna aktarabilir. Örneğin: HERE LABEL FAR MOV DX, 0 Etiketler MOV direktifidir. ‘HERE’ Zaten sözcük değerlerinin tablosundaki byte’lara ve aktaramazsınız. Örneğin, 80286 birbirini izleyen B_TABLE isminde byte tablosu ya da W_TABLE isminde sözcük tablosunu tanır. B_TABLE LABEL BYTE W_TABLE DW 2F24H, 36AH, 0817H,3 5.4.2.Şartlı Direktifler: Şartlı direktifler assembler’a assembler zamanında “true” ya da “false” belirtilmediği tabanda kaynak ifadelerin ayarının derlenmesine ya da atlanmasına neden olur. Bu seçici derleme/derlememe yeteneği deneme çalışmalarında taşhis edilmiş ya da ya da özel durumların yerleştirilmesine ya da çokamaçlı programıların özelleştirilmiş sürümlerinin yaratılmasında size izin verir. “Şartlı derleme” programın bir parçasıdır. IF direktifinden önce gelir. (bkz Tablo.5.3.) ve ENDIF direktifiyle izler. Her durumda, deneme durumu “true” olarak değerlendirirse kapsanmış 95 kod derlenmiştir.; deneme durumu “false” olarak değerlendirilmişse assembler kodu atlar. Ve ENDIF’ten sonraki ifadeyle devam eder. Devamında, grupta 4 çift içinde 8 tane IF direktifi kullanabilirsiniz. IFE – “true” ise açıklaması “0’dır”; IF “true” ise açıklaması “0 değildir”. IF1 assembler 1’i çalıştırmaya geçerken “true” dur. IF2 2’yi çalıştırmaya geçerken “true” dur IFDEF simge tanımlanmış ya da EXTRN direktifiyle dışsal olrak bildirilmişse “true” dur; aksi halde IFNDEF “true” dur. IFIDN stringlerde parça-1 ve parça-2 özdeşse “true”dur; farkılı ise IFIDF “true” dur. Tablo.5.3. Şartlı Direktifler Direktif Fonksiyon IFE Biçimi: IFE ifade İfade “0” sa “true” IF Biçimi: IF ifade İfade “0” değilse “true” IF1 Biçimi: IF1 Assembler 1 .çalışma geçişinde “true” IF2 Biçimi: IF2 Assembler 2. çalışma geçişinde “true” IFDEF Biçimi: IFDEF simge Simge tanımlanmış ya da EXTRN direktifiyle dışsal olarak bildirilmişse “true” IFNDEF Biçimi: IFNDEF simge Simge tanımlanmamış ya da EXTRN direktifiyle dışsal olarak bildirilmemişse “true” IFIDN Biçimi: IFIDN <string>, <string> 96 string1 ve string2 özdeşse “true”. Köşeli parantezler gerekli Biçimi: IFIDNF <string>, <string> IFIDF string1 ve string2 farklıysa “true”. Köşeli parantezler gerekli Örneğin, Deneme çalışmasında teşhisli yordamlar içermesi için, bunları IFE ve ENIF ile kapsar ve sabit çağrılmış FOR_TEST_ONLY ayarlanır. Aseembly zamanında, assembler FOR_TEST_ONLY’nin değerini denetler. Eğer 0’sa : teşhisliler programın içinde bulunmaktadır. (kapsar). Eğer FOR_TEST_ONLY başka bir değerdeyse, teşhisliler atlanmıştır. Program bu formda olacaktır. IFE DIAG1 : FOR_TEST_ONLY ------ (teşhis deneme direktifi) ----ENDIF İfade yalnızca FOR_TEST_ONLY = 0 gibiyse direktif DIAG1 ve ENDIF arasında derlenir. İfade FOR_TEST_ONLY = 1 Programda daha erken görünür. Assembler direktifleri DIAG1 ve ENDIF arasında atlar. 5.4.2.1.ELSE Seçeneği: Zaten siz ELSE terimi içererek “false” durumu için değişik direktif ayarı üretebilirsiniz. Genel Biçimi: IFXX [argument] durumu ---- (ifade “true” durumu için) ---[ELSE] (ifade “false” durumu için) ---97 ---ENDIF ELSE seçeneği size izin verir. Örneğin,bir programın iki sürümünü yapıyorsunuz: Biri ekrana İngilizce mesaj yazıyor diğeri ise Türkçe mesaj yazıyor.Bunu yapmak için sabir LANGUAGE çağrısını ayarlamak, seçip talimatları her iki dil için paylaştırmak gerekiyor. Eğer LANGUAGE değeri 0 ise assembler İngilizce sürüm üretecek; eğer LANGUAGE değeri 1 ise, Türkçe sürüm üretecek. Program mesaj tabanlı bölümü bu formdaki gibi olur. IFE LANGUAGE ---- (İngilizce-üretme ifadesi) ---ELSE ---- (Türkçe-üretme ifadesi) ---ENDIF 5.4.2.2.Yuvalama Şartları: Yuvalama şartı tümcecikleriyle assembler’a ikiden fazla seçenek verebilirsiniz. Örneğin; varsayalım programınızın Türkçe sürümünü gerçekten yakaladınız, ve diğer sürümleri üretmeye karar verdiniz. Ekrana Fransızca ve Almanca mesajlar yazan sürümler. Bunu yapmak için programı değiştirmeliyiz. Böylece Assembler dil tabanlı LANGUAGE 1,2 ya da 3 değerlerini (İngilizce, Türkçe, Fransızca, Almanca) seçer. Şimdi mesaj bölümü bu yapıya sahip olur. IFE LANGUAGE ----- (İngilizce-üretim ifadeleri) ----ELSE IFE ----- LANGUAGE_1 (Türkçe-üretim ifadeleri) 98 ----ELSE IFE LANGUAGE_2 ----- (Fansızca-üretim ifadeleri) ----ELSE ----- (Almanca-üretim ifadeleri) ----ENDIF ENDIF ENDIF Not: IFE blokları dengelemek için 3 ayrı ENDIF’e ihtiyacımız var. Not: Zaten programı kolya okunur yapmak içn IFE – ENDIF çiftlerini girintili hale getirdik. 5.5. Makrolar : 5.5.1.Makrolarla Tanışma: Bir makro program içinde birkaç kere görünen assembler ifadesi (talimatlar ve direktifler) dizisidir. Prosedürlerde olduğu gibi, makronun da ismi vardır. Bir defa makro. Kaynak progeamınızın talimat dizisinde makronun ismini normal tipte girebilirsiniz. 5.5.2.Makrolar Prosedürlere Karşı: Her ne kadar makrolar ve prosedürlerin her ikiside kısa, kullanımı kolay talimat dizisini desteklersede, ancak bunlar aynı değildir. Kod prosedür için bir kere meydana gelir. Ve işlemci kodu zorunlu olarak transfer eder. (CALL “code”) Aksine, makro için program içinde birkaç defa meydana gelebilir. Her meydana gelemsinde isim sunumlu talimatlarla makro ile assembler yerini değiştirir. (yani assembler makroyu “genişletir”). Böylelikle; programı çalıştırdığınmızda, prosedürmüş gibi işlemci makro talimatını “hatta” belleğin başka bir yerine aktarmadan çalıştırır. Bir makro ismi kullanıcı-tanımlı bir assembler direktifidir. Makro assembler komutlarını mikroişlemciden daha iyi sağlar. Makrolar prosedürlere göre 3 avantaja sahiptir. 99 Makrolar “dinamiktir”. Giriş parametrelerini değiştirerek kolayca makronun işletimini (yalnızca o an işlettiğini) her zaman değiştirebilirsiniz. Aksine prosedürde bunun için yalnızca verileri değiştirebilirsiniz. Prosedür yapmak daha az esnektir. Makrolar programları hızlı çalışır yapar. Çünkü işlemci prosedürlerdeki gibi, çağırma ve döngü talimatlarıyla durdurulmuştur.Makrolar programcıların diğer programlarda yaratmış olduklarından çekmek için “makro kütüphanesi”ne girebilirsiniz. (*.mlb, *.lib) 5.5.3.Makrolar Programlamayı Hızlandırır: Makrolar programlamayı hızlandırabilirlerve gelecekte programı güncelleyeceğinz zaman çalışmayı ayıklar. Makrolar bir kere yarattığınızda programın istedğiniz yerinde kullandığınız zaman programlamayı hızlandırır. Uzun talimat dizileri girmek yerine, yalnızca makro ismini girin, bu isimi makroyu ifade eder. (Makrolar alt prosedürlerle ortak olarak bunlara sahiptirler) Makrolar ayıklama işini de hızlandırır. Çünkü ayrı olarak her makroyu yaratır ve ayıklarız. Birincisi makro uygun bir şeklide çalışır. Programınızın bu parçası doğru diye endişe etmezsiniz. Herhangi bir hata bulmaya konsantre olabilirsiniz. Makro içeren programlar genellikle daha kolay okunur ve anlaşılırlar. Bu aynı zamanda daha kolay güncelleneceği anlamına da gelir. Makroların nasıl çalışma yükünüzü azalttığını görün. Talimatların ekran üzerine karakter göstermek için aldığını düşünün. Bu 21AH=2 seçeneği tipini kapsar. Bir D göstermek için; Örneğin, MOV AH, 2 ; karakter gösterme seçeneğini seçer. MOV DL, ‘D’ ; karekteri belirtir. INT 21H ; DOS’un 21h kesmesini çağırır. Benzer şekilde bir E göstermek için gereken MOV AH, 2 ; karakter gösterme seçeneğini seçer. MOV DL, ‘E’ ; karakteri belirtir. INT 21H ; DOS’un 21h kesmesini çağırır. Varsayalım ki zaman zaman değişik harfler gösteren bir programınız var. Bölümünüzde ne içerir. Her zaman aynı talimat dizisinde girmeyi (hatırlatmayı) içerir. Ya da alt prosedürün içinde dizi koymayı içerir. Düzgün bir alt prosedürle, her gösterme noktasında iki talimat girebilirsiniz. Bunlar: 100 MOV DL, ‘E’ ; Bir E gösterir. CALL SHOW_CHAR Bazı durumlarda, zaten bu talimat dizileri kısadır. Bu ihtiyacınız olduğu zaman bunları yeniden girmek hala sıkıntı verir. Bununla birlikte, makro gibi basit dizi tanımlamışsanız. Yerine aşağıdakilerden birini girebilirsiniz. SHOW D ; D gösterir SHOW E ; E gösterir SHOW Y ; Y gösterir Hangi teknolojinin kullanılması ve anlaşılması daha kolaydır. Üç talimatlı dizi ya da bir çizgi makro ? En son olarak, zaten makrolar programı değiştirmeyi kolaylaştırıyor. Makro tanımını değiştirir ve assembler kendiliğinden bu yeni sürümü her yerde öneki eskisinin yerine kullanır. 5.5.4.Makroların İçeriği: Her makro tanımı 3 bölümden oluşur. Başlık: MAKRO direktifi etiket alanında makronun ismiyledir ve seçimlik olarak operand alanında bir durgun-listedir. Durgun-liste sizin her zaman makroyla çağıracağınız giridi parametrelerini ve değişkenleri belirtir. Gövde: Assembler talimatları dizisi (talimatlar ve direktifler) makronun ne yapacağını tanımlar. Sonlandırıcı: ENDM direktifi, makro tanımını bitiren işaret. ENDM’yi atlarsanız, assembler hata mesajı gösterir. “End of file encountered on input file” Örneğin, Aşağıdaki basit makroylasözcüğün boyu değerini ekleyebilirsiniz. ADD_WORKS MAKRO TERM1, TERM2, SUM MOV AX, TERM1 ADD AX, TERM2 MOV SUM, AX ENDM Assembler operandlar için saklayıcı isimlerini, bellek bellek bölgesini ve yakın değeri belirtmediğiniz zaman dikkat etmez. (Şüphesiz SUM için, kesin kullanamazsınız.). Uzunca son için geçerlidir.. Assembler yerine koymaları sorunsuz bir şekilde yapar. Örneğin: Programın bir yerinde, aşağıdaki kodu girerek iki bellek bölgesi ekleyebilirsiniz. 101 ADD_WORKS PRICE, TAX, COST Bu kodla assembler programda aşağıdaki talimatları ekler. MOV AX, PRICE ADD AX, TAX MOV COST, AX Bazı yerlerdeyse iki saklayıcı ekleyebilirsniz. Böyle: ADD_WORKS BX, CX, DX Şimdi de assembler bunları girer. MOV AX, BX ADD AX, CX MOV DX, AX NOT: Geçiş parametreleri makrolarda prosedürlerden ne kadar daha kolay. Bir makroyla, yalnız parametreyi girersiniz, bir prosedürle, bunu ya bir saklayıcının içine yada bellek bölgesine koymalısınız. 5.6.Makro Direktifleri: Tablo.5.4, Microsoft Macro Assembler desteklediği makro direktfilerini özetlemektedir. Bunları biz 4 gruba böldük – Genel amaçlı, döngü, şatrlı ve listeleme olarak... Tablo.5.4. Makro Direktifleri Direktif İşlev Genel Amaçlı MACRO Biçim: isim MACRO [durgun-liste] --------ENDM Assembler tallimat dizisinin ismini belirler. Her MACRO tanımını ENDM yalancı operandıyla bitirmelisiniz. 102 LOCAL Biçim: LOCAL durgun-liste Assembler durgun-listenin içine her giriş için tek simge yaratır. Her girişin genişlemesi görüldüünde bunu yerine koyar. Döngü IRP Biçim: IRP durgun, <argüman listesi> --------ENDM Assembler her argüman listesi için birkez talimatı IRP ve ENDM arasında döndürür. Her dönmede her blok içindeki durgunun gözükmesi için <argüman-listesi> yeni öğeyi içine koyar. IRPC Biçim: IRPC durgun, string --------ENDM Assembler string’in içindeki karakter için birkez yapıyı IRPC ve ENDM arasında döndürür. Her dönemde her blok içindeki durgun’un gözükmesi için “string”in içine yeni karakteri yerine koyar. REPT Biçim: REPT açıklama --------ENDM Assembler “açıklama” zamanlarıyla talimatı REPT ve ENDM arasınd döndürür. Koşullu: 103 EXITM Biçim: EXITM Koşullu yalancı operandın sonucunda genişleme tabanlı makroyu sonlandırır. IF1 Biçim: IF1 açıklama --------ENDIF True ise assembler 1.’yi çalıştırır. Genellikle kaynak programı içinde INCLUDE bir makro kütüphane dosyasıyla kullanılır. IFB Biçim: IFB <argüman> ------ENDIF True ise argüman boş. Köşeli parantezler gerekli. IFNB Biçim: IFNB <argüman> --------ENDIF True ise argüman boş değil. Köşeli parantezler gerekli Listeleme .LALL Biçimi: .LALL Bütün genişlemeler içi (yorumlarıyla birlikte) bütün makro metini listeler. 104 .SALL Biçimi: .SALL Makro metnini listelemelerden çıkarır. .XALL Biçimi: .XALL Makro çizgilerini yalnız ürettiği nesne koduyla listeler. Bu varsayılan ayardır. 5.7.Genel-Amaçlı Direktifler: Biz zaten MACRO direktiflerini tartışmıştık. Bu makronun ismini verir, makronun kullandığı operand isimlerini listeler. 5.7.1.LOCAL Direktifi: Eğer sizing makronuz etiketli talimatlar ya da direktifler içeriyorsa assembler’a her zaman etiketleri değiştirmesini söylemelisiniz. Bu makroyu genişletir. Aksi halde, “Symbol is MultiDefined” hatasıyla karşılaşırsınız. LOCAL direktifi assembler’a her zaman hangi etiketi değiştireceğini söyler. Örneğin, Aşağıdaki makro’da (WAIT) makro işlemciyi COUNT değerine kadar bekletir. Taki 0’a düşene kadar. “NEXT” LOCAL etiketi program içinde birkezden fazla kullanmamıza izin verir. WAIT MACRO COUNT LOCAL NEXT NEXT: PUSH CX MOV CX, COUNT ; Güncel CX’i sakla LOOP NEXT POP CX ENDM Not: LOCAL kesinlikle MACRO talimatı takip eder. Eğer LOCAL kullanılmışsa makroda ilk yapı olmalıdır.Onlar herşeyden önce gelmelidir. 105 Bir LOCAL etiketi bildirirken zaten diğer makroların altında gelir. Assembler etikete her zaman yeni iç ad verir. Bu makroyu genişletir; yalnız kopyalama yoktur. 5.7.2.Döngü Direktifleri: REPT, IRP ve IRPC direktifler assembler’a makro içine assembler talimat dizilerinin dönmesini sağlar. REPT operand alanındaki alanındaki açıklamayla dönme sayacı oluşturur. Örneğin: aşağıdaki makro LNGTH byte’ları bellekte ayırır. Ve LNGTH arasında 1’le olanları başa getirir. (tek tek) ALLOCATE MACRO TLABEL, LNGTH TLABEL EQU THIS BYTE VALUE = 0 REPT LNGTH VALUE = VALUE + 1 DB VALUE ENDM ENDM Not: Burada iki ENDM’ye ihtiyaç duyduk. İlki REPT’in sonu, ikincisi MACRO tanımının sonuydu. ALLOCATE tanımladıktan sonra, bunu bir 40-byte’lık tablo ayarlamak için kullandık. TABLE1 isminde, bu diziyle DATA SEGMENT PARA ‘DATA’ ALLOCATE TABLE1, 40 DATA ENDS İkinci döngü direktifi, IRP her dönmeyle liste argümanı durun simge için yerine koymanıza izin verir. Örneğin bu dizi: IRP VALUE, <1,2,3,5,7,11,13,17,19,23> DW VALUE * VALUE * VALUE ENDM İlk on baş numaralarının küpünü içeren tablolardır. IPRC, IRP gibidir, ama argümanları olan string değişkenler numaralardan daha iyidir. IPRC iki operand alır. Bir durgun simge ve bir string ve string içinde her karakter için blok içindeki 106 talimatları birkez döndürür. Her dönmede blok içinde her durgun’un görünmesi için string içine bir sonraki karakter koyulur. Örneğin, Bu dizi IRPC CHAR, 0 1 2 3 4 5 6 7 8 9 DB CHAR ENDM 0 ile 9 arasında basamak içeren ASCII kodlar içeren 10-byte text bir string ayarlar. 5.7.3.Şartlı Direktifler: Assembler hangi şartın tatmin edip etmediğini test eder. Assembler taimat IF ve ENDIF arasındaysa derler değilse atlar. 5.7.4.IF1 Direktifi: IF1 direktifi kaynak programdan makro kütüphanesi okunduğunda kullanılır. 5.7.5.IFB Direktifi: Makronun istediğinden daha az parametre girdiğinizde, assembler normal olarak atlanmış veya “boş” parametreleri sıfıra ayarlar. Bununla birlikte, IFB (if blank) boş parametreler için bazı değişik eylem yolları belirtmenize izin verir. IFB genel olarak bazı gerekli parametreler kaçırıldığında makroyu erken sonlandırmada kullanılır. Biz bu bölümde EXITM ‘yi erken sonlandırma hakkında daha çok şey söyleyeceğiz. 5.7.6.IFNB Direktifi: Assembler IFNB (if not blank) ile karşlaştığında yalnızca kullanızının parametreler için bir değer verdiği talimatları derler., aksi halde atlar. Örneğin, Bir makro bu form kullanılarak çağrılan dışlanmış olabilecek bir ismi okur. GET_NAME FIRST_NAME, MIDDLE_INITIAL, LAST_NAME GET_NAME için makro tanımı ilk ismi oluşturan talimatı içerir, sonra ortadaki, sonra son ismi içerir. Bununla birlikte herkesin orta ismi kullanmamaması yüzünden atlama hükmü olabilir. Bunu IFNB kullanarak yapabilirsiniz. Orta isim talimatları yalnız kullanı girerse işler. Böylece GET_NAME’in tanımı izleyen genel form’daki gibidir. GET_,NAME MACRO ilk_isim, orta_isim, son_,isim ----- (Bu talimatlar ilk ismi okur) 107 ----IFNB <middle_initial> ----- (Bu talimatlar orta ismi okur) ----- (Bu talimatlar son ismi okur) ENDIF ----ENDM Bu sayede siz bu makrodaki gibi “GET_NAME” Mehmet Tektaş girebilirsiniz ve assembler hata vermez.IFNB operand kayıplarından oluşabilecek kayıplara karşı assembler’yi korumaya yardım eder. Eğer makro PUSH reg_name talimatı içerirse reg_name parametre listesinden atlanır.Assembler PUSH 0 ile girintili değer üretir. Buna karşı korunmak için IFNB <reg_name> PUSH reg_name ENDIF kullanın (Bu durumda, muhtemelen benzer bir konuma POP reg_name eşlemesine de gerek duyulur.) 5.7.7.EXITM Direktifi: EXITM (Exit Macro) direktifi assembler’ın genişlemiş makroyu erken durdurmasına neden olur. Koşullu direktifin sonuucu tabanlı böyledir. IFB <name> EXITM ENDIF Örneğin, REPT direktifiyle tanımladığımız ALLOCATE makrosunu yeniden çağıralım. Aşağıdaki yeni tanımlama assembler’ı tabloyu yalnız LNGHT parametresi 50’nin altında tahsis eder yapar. ALL_LT_50 MACRO LNGTH VALUE = 0 IF LNGTH GE 50 EXITM 108 ENDIF REPT LNGTH VALUE = VALUE + 1 DB VALUE ENDM ENDM 5.7.8.Listeleme Direktifleri: .LALL, .SALL ve .XALL direktfileri.“Assembler listelemesinde (LST)” Makro text’in içerdiği makroların sayısını kontrol eder. Bu seçeneği atlarsanız assembler .XALL istediğinizi varsayar. Bu ise yalnızca üretilen nesne kodunu ve yorumu ve bellek bölgesine geri dönmeyen direktifleri listeler. .LALL direktifi tam listeleme üretir. Yorumları da içerir. .SALL listelemeden bütün makro text’leri atlar. .LALL kullanırsanız sizin dosyanız için programın bir kopyasını üretir. .SALL kullandığınızda tamamen ayıklanmış makrolar listelenenecektir. 5.8.Makro Operatörleri: Makro assembler kullanabileceğiniz 4 operatörü destekler. Tablo.5.5.’e bakınız... Tablo .5.5. Makro Operatörleri: Operatör İşlev & Biçim: text & text Text ya da simgeleri birleştirir. ;; Biçim: ;; yorum Listelemeden ve makro genişlemesinden yorumu atlar. :LALL ile aynıdır. ! Biçim: ! karakter Argümanda kullanıldığında assembler karakteri durgun değer gibi kullanır, simgeden daha iyidir. % Biçim: % simge 109 Sembolü sayıya çevirir. Assembler makroyu genişlettiğinde simge için sayı yerine konur. 5.8.1. & Operatörü: & operatörü size özel etiketler ya da operandlar yaratmanıza izin verir. Örneğin, Aşağıdaki makro isim ve uzunluğu tanımlanmış bir byte tablosu ayarlar. DEF_TABLE MACRO SUFFIX, LNGTH TABLE & SUFFIX DB LNGTH DUP (?) ENDM Programda DEF_TABLE ‘ a A,5 girerseniz assember buna çevirir. TABLE DB 5 DUP (?) 5.8.2. ;; Operatörü: ;; operatörü assembler’a makro genişlemesinden yorumları atlatır. Yorumsuz sizin son programınız bellekten daha az yer alır ve böylece daha hızlı derlenir. Makro tanımlarken, düzenli; kullanın yalnızca yorumların kesinlikle gerekli olduğu durmlarda kullanın. 5.8.3.Kaynak Programın İçinde Makro Tanımlamak: Makro kullanmanın iki yolu vardır. Ya doğrudan tanımlamaları program içine girersiniz. Ya da birkaç makro kütüphanesinden okutursunuz. Bu bölümde biz program içine nasıl makro gireceğinizi tanımlayacağız. Özel amaçlı makronuz varsa yalnız bir programın içinde tanımlayabilirsiniz. Sonra çağırma gereklidir. Varsayalım; örneğin SHOW makrosu kullanmak istiyorsanız. SHOW tanımı böyledir. SHOW MACRO karakter ;; Tanımlanmış karakteri gösterir. PUSH AX ;; etiketlenmiş tutucularını saklar PUSH DX MOV AH, 2 110 MOV DL, ‘karakter’ INT 21H POP DX POP AX ENDM Bu materyali programın başına girin. Kesinlikle TITLE talimatından sonra ... Programın içine doğrudan makro girmenin dexavantajı program parçasının sınırlarıdır. Diğer programlarda kullanmak içiin makro kütüphanesinin içine koyabilirsiniz. 5.9.Makro Kütüphaneleri: Bir makro kütüphanesi birkaç programda ihtiyaç duyacağınız. Tanımlamalar içeren bir disk dosyasıdır. İlk kez bu dosyayı yarattığınızda birkaç kaynak programın içinde bunu okutabilirsiniz. Aynı isimle başka yerlerde de kullanabilirsiniz. 5.9.1.Makro Kütüphanesi Oluşturma: Makro kütüphanenelerini EDLIN ya da herhangi bir kelime işlemciyle yaratabilirsiniz. 5.9.1.1.Makro Tanımlama İçin Rehber: Makroları bir kütüphane içinde kullanabilmeniz için sanal olarak programın içinde genel amaçlı rutünler olabilir. Böylelikle değişik görevler için bunları tasarlayabilirsiniz. Ama programda bunları kullanırken çakışma olmamalı. Verimli makrolar tanımlamak için tüyolar: Belge makroları aşağı yukarı mümkündür. Birçok yorum içerir. Hatırlayın; makro tanımlamalarınız onu kullananlar için anlamlı olmalıydı, yalnızca sizin için değil. Yorum girmek için ;; operatörünü kullanın ve alanları tab tuşuyla ayırın. (boşluk tuşundan daha iyidir). Bu programınızın boyutunu en azda tutmada size yardımcı olur, daha hızlı derlemenize izin verir. Makroları genel olarak saklamanız mümkündür. Özel-amaçlı makroya gerek duyarsanız; bir başka genel amaşçlı makro kullanırsınız. (eğer mümkünse) Örneğin, varsayalım LOCATE isimli bir makronuz var. Bu imleci tanımlanmış sıra ve sütuna konumlandırıyor. Bir çağrıda LOCATE formunu kullanır. Sıra-sütun sonra siz HOME isminde bir başka makro tanımlamak istediğinizde imleci üzt sol köşeye taşır. HOME’un tanımı basitçe LOCATE 0,0’dır. 111 Makro label içeriyorsa, LOCAL talimatının içine yazın. Her saklayıcısı saklamak için dış saklayıcıları dışlayan makrolar kullanın. Bunu yapmak yararlıdır. PUSH’larla makroyu başlatın POP’larla sonlandırın. Makro tanımı önceden tanımlı makroyla gerçeklenmiş bir görevi gerçekleştiriyorsa, bunu yapmak için bir makroyu çağırın. 5.9.1.2.Bir Program İçine Makro Kütüphanesi Okutmak: Bir kaynak programını içine bir makro kütüphanesi okutmak için assembler’a INCLUE talimatıyla bir isim vermelisiniz. Bununla birlikte bunu sadece böyle yaparsınız. INCLUDE MACRO.LIB Dönmeden kaçınmak için INCLUE’u bir IF1 şartlı talimatı içine koyarsınız. IF1 INCLUDE MACRO.LIB ENDIF 5.9.1.3.Makroları Temizlemek (Arındırmak): INCLUDE’ları assembler kullanıldığında makro kütüphanesi kütüphanesi kullanımının bir dejavantajı; bütün okunan makrolar belleğin assembler’ın çalışma boşluğunda saklanır. Bu içerik makroları assembler tarafından lkullanılmayacaktır. Böylece çalışma boşluğu muhtemelen “out of memory” hata durumu yaratacaktır. Bu sorundan sakınmakiçin gereksiz makroları arındırabilirsiniz. Bunu yapmak için INCLUDE’dan sonra kesinlikle arındırma öğeleri ekleyin. Basitçe: INCLUDE MACRO.LIB PURGE SHOW, CLS, HOME, LOCATE olur. 5.10.Nesne Kütüphaneleri: Daha önce makro kütüphanelerinin nasıl yaratılacağından bahsettik. Disk dosyaları makro tanımlamaları içindedir. Bir kütüphanede birkaç makro kullanmak basitçe programınızın içine INCLUDE ile tüm kitaplığı alabilirsiniz. (Ve makronun ismi). Böylece makro kütüphaneleri her programda gerektiği yerde sizi yeniden yazmaktan kurtarır. 112 Makro Assembler program modülleri için banzer olanakları destekler. Özellikle nesne kütüphaneleri yaratmanıza izin verir. Nesne kütüphanesi içinde birkaç prosedür kullnamak için prosedürü CALL ile çağırıp dışsal olarak (EXTRN direktifiyle) bildirebilirsiniz. Sonra link olayını çağırdığınızda kütüphaneyi program modülüyle link edersiniz. Link edici kendiliğinden çağrılmış prosedürü açacaktır. Bir nesne kütüphanesinin diske bir prosedür olarak kaydedileceğini hatırlamalısınız. Ardından kaçınılmaz disk-sorunlu iş gelebilir. Şu anda nesne kütüphanesi içeren birini yalnızca bir diskin Track’ine saklamalısınız. Bir nesne kütüphanesi bir hard diske sahipseniz uygundur. Çünkü Link komutuyla bir bireysel modülü belirtmek için kaydeder. Basitçe link kütüphaneye programı çağırır ve link aracı gereken modülü açar. 5.10.1.Nesne Kütüphaneleri İnşa Etmek: Assembler diskinde nesne kütüphanelerini tutan program LIB.EXE (Kütüphane Yöneticisi) dir. Bir nesne kütüphanesi yaratmak için LIB yazmalı ve kütüphanenin içine komak istediğiniz. İlk nesne modülünü belirtmelisiniz. Bunu yapmak için assembler diskini A sürücüsüne , nesne modülünü içeren diski B sürücüsüne koumalısınız. Sonra bilgisayarı uygun bir şekilde açın. Ekranda B> konumuna geçin. Sonra bu komutu girin. a : lib kutismi + nesnemodulu ; LIB.EXE kendiliğinden LIB ve OBJ uzantılarını kütüphane ve nesne modülü ismi için destekler. Örneğin: İlk girişte nesne.lib ile siralama.obj isimli kütüphane yaratmak için şunu girin; a : lib nesne + siralama ; 5.10.2.Nesne Kütüphanelerini İşletmek: İlk kez bir kütüphane yarattınız. Önceki komutu tekrarlayarak yeni modüller ekleyebilirsiniz. Örneğin NESNE adlı kütüphaneye MULU32.OBJ modülü eklemek için şunu girin a : lib nesne + mulu32 ; (+) kütüphane ekle anlamındadır. Kütüphaneden bir modül silmek için (+) yerine (-) kullanmalısınız. Örneğin MULU32’yi silmek için a : lib nesne - mulu32 ; Siz ayrıca kütüphaneden bir modülü kopyalamak isteyebilirsiniz. Belkide onu başka bir kütüphaneye eklemek için. Bu * operatörünü gerektirir. Örneğin siralama.obj ‘nin bir kopyasını yapmak için. a : lib nesne * siralama ; bundan sonra SIRALAMA hala kütüphanenin içindedir. Ancak siralama.obj adında bir kopyası daha diskin içindedir. 113 LIB.EXE tamel işlemleri birleştirmenize izin verir. “-+” operatörü bir kütüphane modülünü başak bir tanesinin içeriğiyle değiştirir. Yani “-+” bir kütüphaneyi günceller. Örneğin: a : lib nesne -+ siralama ; NESNE kütüphanesinden SIRALAMA modülü kaldırır. Diskten SIRALAMA.OBJ ‘nin içeriğini içine koyar. Benzer bir şekilde “-*” kütüphaneden bir nesne modülü kaldırır. Ancak diske bir kopyasını yaratır. Örneğin: a : lib nesne -* siralama ; NESNE kkütüphanesinden SIRALAMA modülünü SIRALAMA isimli yeni bir dosyaya tşır. 5.10.4..Bir Kitaplığın Bir Dizinini Elde Etme: Kütüphane içindeki nesne modüllerinin ne ne olduklarını unuttuysanız LIB.EXE’yi dizin dosyası üretmek için kullanabilirsiniz. Bunu yapmak için bu bu komutu giriniz. a : lib kutismi , kutüsmü.dir ; sonra, dizini görüntülemek için ; type kutismi.dir nesne modüllünün isminin yanında dizin listeleri simgeleri herbiri içinde PUBLIC olarak bildirilir. Bu kütüphane içinde programı çağırırken hangi prosedürlere, değişkenlere ve eşitliklere başvuracağınızı söyler. 5.10.5.Nesne Kütüphanelerini Kullanma : Bu bölümün başında ifade ettğimiz gibi. Bir nesne kütüphanesi kullanmak için nesne modülü (ya da modülleri) içeren programınızı “link” etmelisiniz. Link aracı bu amaç için bir özel ileti gösterebilir. a : link modül , , NUL Ekran gösterdiğinde ; Libraries [.LIB] : kütüphanenizin ismini girin enter’a basın Örneğin . NESNE kütüphanesini link etnek için; bu nesne modülü MAIN_PROG tarafından çağrılıyor olsun 114 a : link main_prog , , NUL girin sonra Libraries [.ILB] : nesne Eğer program birkaç farklı kütüphaneden nesne modülü gerektiriyorsa Libraries iletisine bunları listeleyerek yanıt vermelisiniz. Libraries [.LIB] : lib1 + lib2 + lib3 115 6.BÖLÜM 6. VERİ YAPILARI 6.1.Veri Yapılarıyla Çalışma: Burada hemen hemen bellekteki bilgiyi düzenlemenin yolları düzenlenmiş bilginin çeşidi gibidir. Bu organizasyonel teknikler uygulamalarla birlikte değişir ve bu isimleri alırlar; diziler, stringler, arama tabloları. Bunlar veri yapılarının bütün farklı çeşitleridir. Veri yapıları konusu birkaç bölüm olabilir. Bu yüzden biz burada bunu geniş olarak vermeyi düşünmüyoruz. Bunun yerine yoğunlaştırılmış olarak temel üç yapıyı vereceğiz: listeler, arama tabloları , metin dosyaları.Listeler element diye adlandırılan verilerin birimlerini bellekte sıralı olarak tutarlar (byte ya da Word). Elemenler bitişik bellek bölgelerini kapladıysa ya da her element liste içinde bir sonrakine “işaretçi” içerdiğinde bağlıysa dizi ardışık olabilir. Bundan başka, elementler rasgele dizili olabilir ya da artan ya da azalan düzende olabilir. Arama tabloları bilinen değere ilişkili olarak tanımlanmış bilgiyi (veri ya da adresten herhangi biri) tutan veri yapılarıdır. Telefon dizini bir arama tablosudur.; bir ismi bilerek, ilişkili bir telefon numarasını arayabilirsiniz.Metin dosyaları mektuplarda, raporlarda ve telefon listelerinde olduğu gibi sayısal olmayan bilgiden oluşur. 6.2.Düzenli Olmayan Listeler: Bizim düzenli toplumumuzda, telefon listeleri alfabetik olarak düzenlenmişken, sokaktaki evlerin numaraları artıyor ya da azalıyorken, düzenli olmayan “hiçbir şey” her nasılsa can sıkıcı görünür. Hala, herşey bir şekilde düzenli olabilir, bu yüzden düzensiz listeler bazı uygulamalarda hayatın bir gerçeğini hatırlatır.Özellikle rastgele veri ya da zamanla değişen veri içerenler... Örneğin: Bilgisayara uyarlanmış istasyonları saat başı sıcaklığı düzensiz listelerden okuyabilir ve üreticiler statikleri bunlardan alarak günlük tutabilirler. Bütün listeler bir element sayaç byte’ından (ya da word) ve bir ya da daha fazla veri elementinden oluşmuştur. Siz bir listeyle çalışırken , genellikle elementleri eklemek ya da çıkarmak ya da kesin kesin değerin birini aramak istersiniz. Bu işlemleri yapmak yeterince kolaydır. 1. Bir element eklemek için; bunu listenin sonuna sakla ve element sayacına 1 ekle. 2. Bir element silmek için; bellekte bir elementi yakarı doğru taşı, sonra element sayacından bir çıkar. 3. Bir değer aramak için; listede birinci elemandan başlayarak her elementi arama değeriyle karşılaştır. 6.3.Bir Düzensiz Listeye Bir Element Eklemek: Örnek.6.1’deki prosedür ADD_TO_UL, bir düzensiz liste yaratmak ya da var olan birine bir element eklemek için kullanılan bir çeşit programdır. Bu durumda, word değerlerini içerir (işaretli ya da işaretsiz). 116 ADD_TO_UL element sayacını CX’ten okur. Veri elementlerini değer için AX’ten tarar. Eğer bu değer listede zaten varsa (ZF’ni son değeri 0’dır), 286 başlangıç adresini DI’nın içinden geri çeker ve element sayacını bir bir arttırır. Prosedürün çalışması ne kadar zaman alır? Bu elementleri sayısını ve aranan değerin listenin içinde olup olmamasına bağlıdır. Birincil etken tarama String (SCASW) talimatını kaç defa yinelemiştir. SCASW (5+8N) kadar döngüde çalışır, N tekrarların sayısıdır. Gelin her durum için zamanlamaları yapalım – değer listenin içinde değildir ve değer listenin içindedir. – N tane data elementi bulunan bir liste için bunlar. Örnek .6.1: Düzensiz listeye bir element eklemek: TITLE ADD_2_UL - Düzensiz listeye ekle ; Düzensiz liste içine AX’ten bir değer ekler ; ekstra segment, bu değer listenin içinde değilse. ; Girdiler : DI = Listenin başlangıç adresi İlk bölge = Liste uzunluğu (word) ; Sonuçlar : Yok ; DI ve AX değiştirilmeden geri donmuştur. ; Assemble with: MASM ADD_2_UL; ; Link with: LINK callprog+ADD_2_UL; PUBLIC ADD_TO_UL CSEG SEGMENT PARA ‘CODE’ ASSUME CS:CSEG ADD_TO_UL PROC FAR CLD ; İleri yönde tarama için, DF=0 yap PUSH DI ; Başlangıç adresini kaydet PUSH CX MOV CX,ES:[DI] ; Word sayacını gidip getir ADD DI,2 REPNE ; DI noktasını birinci veri elementi yap SCASW ; Değer zaten listenin içinde mi? POP CX JNE ADD_IT POP DI RET ; Evet. Başlangıç adresini yerine koy ; ve çık. ADD_IT: MOV ES:[DI],AX ; Hayır. Onu listenin sonuna ekle POP DI ; sonra element sayacını güncelle INC WORD PTR ES:[DI] RET ; ve çık. ADD_TO_UL ENDP CSEG ENDS END 117 Aranan değer listenin içinde değilse, SCASW talimatı N defa çalışır. Prosedürde kalan diğer talimatlar bir defa çalışır, 44 döngü olur. Böylelikle, Çalışma zamanı = 5 + 8N +44 = 8N + 49 döngüdür.Böylece, 100 elementli bir listeye bir element eklemek 849 döngü alır. <<849 döngü ya da 6Mhz’de141.78µ.>> Aranan değer listenin içindeyse, 286 yarleştirme yapmak için N/2 karşılaştırmalarının bir ortalamasını alır. Çünkü zamanın yüzde 50’sinde bir aranan değer listenin alt yarısında, ve zamanın diğer yüzde 50’sinde üst yarısındadır. Teorik olarak bu tarama (5 + 8N) kadar döngü alır anlamına gelir. Prosedürde kalan diğer talimatlar ek olarak 29 döngü alır. Böylelikle, ortalama olarak, Çalışma Zamanı = 5 + 4N + 29 = 4N + 34 döngü olup böylece, 100 elementli bir düzensiz listede bir element aramak ortalama 434 döngü alır, << ya da 6MHZ 72.48µ >> 6.4.Düzensiz Bir Listeden Bir Element Silmek: Düzensiz bir listeden bir element silmek için, bulmanız ve sonra elementlerin bir yukarısına bir konum taşımanız gerekir. Bunu yaparken silmenin üzerine “hedef” yazarsınız. Element kaldırıldıktan itibaren, element sayacını bir bir azaltın (listenin birinci bölgesi). Göstermek için, Şekil.6.1.a, bellekteki byte’ların listesini gösterir. Listenin 6 elemente sahip olmasından itibaren, ilk bölge (LISTE) 6.değerini tutar. Şekil.6.1.b, listenin dördüncü elemanı (14) silindikten sonra nasıl göründüğünü gösterir. LİSTE 6 LİSTE 42 42 76 76 122 122 14 SİLİNİYOR 97 LİSTE +6 5 97 LİSTE+5 8 8 ADRESİN ARTMASI (a) SİLMEDEN ÖNCE (b) SİLMEDEN SONRA Şekil.6.1. Silme eylemi listeye etkisi 118 Liste bundan sonra 5 data elementine sahiptir ve 97 ve 8 değerleri bellekte bir yukarı taşınmıştır. Silinmiş değer yok edilmiştir. Örnek.6.2’deki DEL_UL prosedürü bu işlemi gerçekleştirir. AX saklayıcısını kullanarak silinecek değeri belirtir. Örnek 5-1’deki gibi DI listenin başlangıcını işaret eder.Talimatlar önce REPNE CX’in içindeki element sayacı ve DI’nın içindeki ilk data elementinin adresini yükler. Sonra listeyi aranan değer için tarar. Bu talimatlar Örnek 5-1 deki olanla özdeştir. Aranan değer listenin içindeyse (ZF = 1), 286 DELETE kısmına atlar DELETE kısmında, işlemci iki yoldan birini alır.. Eğer element silinmişse listenin en sonundadır (CX sıfır içerir). 286 listenin element sayacını basitçe azalttığında DEC_CNT kısmına atlar Eğer silme hedefi listenin hiçbir yerinde yoksa, NEXT_EL kısmındaki döngü bütün kalan elementleri bir yukarı konuma taşır, hedefin üzerine yazma. Element sayacı bir azalarak silme eylemini yansıtır. Örnek.6.2: Düzensiz Listeden bir Element Silmek TITLE DEL_UL - Düzensiz listeden sil ; Düzensiz liste içindeki AX’ten bir değer siler ; ekstra segment, bu değer listenin içindeyse. ; Girdiler : DI = Listenin başlangıç adresi İlk bölge = Liste uzunluğu (word) ; Sonuçlar : Yok ; DI ve AX değiştirilmeden geri dönmüştür. ; Assemble with: MASM DEL_UL; ; Link with: LINK callprog+DEL_UL; PUBLIC DEL_UL CSEG SEGMENT PARA ‘CODE’ ASSUME CS:CSEG ADEL_UL PROC FAR CLD ; İleri yönde tarama için, DF=0 yap PUSH BX PUSH DI ; BX ‘saklayıcısını kaydet ; ve başlangıç adresini MOV CX,ES:[DI] ; Element sayacını gidip getir ADD DI,2 REPNE SCASW JE DELETE POP DI ; DI noktasını birinci veri elementi yap ; Değer zaten listenin içinde mi? ; Eğer öyleyse, sile git. ; Aksi halde,saklayıcıları yerine koy POP BX 119 RET ; ve çık. ; Aşağıdaki talimatlarda listeden bir element silinir, ; bunları izleyerek: ; (1) Element listenin sonunda duruyorsa, ; element sayacını 1 azaltarak elementi sil. ; (2) Aksi halde, elementi sonradan gelen tüm elementleri, ; bir konum yukarı kaydırarak sil. DELETE: JCXZ DEC_CNT ; Eğer (CX) = 0, en son elementi sil. NEXT_EL: MOV BX,ES:[DI] ; Liste içinde bir element yukarı taşı MOV ES:[DI-2],BX ADD DI,2 ; Sonraki elementi işaretle LOOP NEXT_EL ; Son element taşınana kadar don DEC_CNT: POP DI ; Element sayacını 1 azalt DEC WORD PTR ES:[DI] POP BX RET ; BX’in içeriğini yerine koy ; ve çık. DEL_UL ENDP CSEG ENDS END 6.5.Düzensiz Listenin İçindeki Maksimum ve Minimum Değerler: Bazen düzensiz lisenin içindeki maksimum ve minimum değerleri bulmak isteyebilirsiniz. Kabul edilebilir yaklaşım ilk önce ilk elementi maksimum ve minimum değerlerin ikisi içinde aranan değer olarak bildirmektir. Sonra listedeki kalan elementleri bu değerlerle karşılaştırın. Eğer programınız en küçükken daha küçük bir değer buldursa, bu değeri yeni minimum yapar, Benzer şekilde, program en büyükten daha büyük bir değer bulursa, bu değeri yeni maksimum değer yapar. Örnek.6.3’ teki MINMAX prosedürü bu yöntemi uygulayarak bir düzensiz listenin DI’nın içindeki başlangıç adresindeki işaretsiz word değerlerini uygular. MINMAX AX ve BX’in içindeki maksimum ve minimum değer sırasıyla geri döner. Örnek.6.3: Düzensiz listelerin içindeki maksimum ve minimum değerler. TITLE MINMAX - Düzensiz liste içinde maksimum ve minimum ; Ekstra segmentin içinden bir düzensiz listenin maksimum ve minimum ; Word’lerini bulur. ; Girdiler : ES:DI = Listenin başlangıç adresi 120 İlk bölge = Liste uzunluğu (Word) ; Sonuçlar : AX = Maksimum ; BX = Minimum ; DI değiştirilmemiştir. ; Assemble with: MASM MINMAX; ; Link with: LINK callprog+MINMAX; PUBLIC MINMAX CSEG SEGMENT PARA ‘CODE’ ASSUME CS:CSEG MINMAX PROC FAR PUSH CX PUSH DI ; Başlangıç adresini kaydet MOV CX,ES:[DI] ; Element sayacını gidip getir DEC CX ; sayaç-1 karsılaştırmaları için hazır ol ADD DI,2 ; İlk elementi işaretle MOV AX,BX ; ve maksimum CHKMIN: ADD DI,2 ; Sonraki elementi işaretle CMP ES:[DI],BX ; Elementi minimumla karsılaştır JAE CHKMAX ; Yeni minimum bulundu mu? MOV BX,ES:[DI] ; Evet. BX’in içine koy JMP SHORT NEXTEL CHKMAX: CMP ES:[DI],AX JBE NEXTEL ; Yeni maksimum bulundu mu? MOV AX,ES:[DI] ; Evet. AX’in içine koy NEXTEL: LOOP CHKMIN POP DI ; Elementi maksimumlar karsılaştır ; Bütün listeyi denetle ; Başlangıç adresini yerine koy POP CX RET ; ve çık. MINMAX ENDP CSEG ENDS END. Bu prosedür iki bölüm içerir. Lk bölüm karşılaştırmaların sayılarını hesaplayarak element sayacını –1 yapar ve ilk data elementini x maksimum ve minimum normlarına göre ayarlar. İkinci bölüm ise yeni minimum ve maksimumu arayarak liste boyuca döngüye girer. Bu bölüm BX’in 121 içine yeni minimumu AX’in içine yeni maksimumu kaydeder.Her ne kadar MINMAX işaretsiz Word değerlerinin listesini işlese de, siz işaretli Word değerlerinin listeleri içinde maksimum ve minimum aramak için onu değiştirebilirsiniz,; basitçe JAE CHKMAX ile JGE CHKMAX’ı ve JBE NEXTEL ile JLE NEXTEL’i değiştirirsiniz. (......) 6.6.Düzensiz Verileri Sıralamak: Eğer bilgiyi zamana karşı çiziyorsanız ya da metin işliyorsanız, bilgiyi düzensiz formada kabul edebilirsiniz. Ancak, bazı uygulamalarda artan ya da azalan düzende düzenlenmiş bilgi daha iyidir. Çünkü bu yolla analiz etmek daha kolaydır.Düzensiz verilerin listesini nasıl yeniden düzenleyebiliriz? Bu konuda literatürün değeri önemlidir. Ama biz bunu genel bir sıralama tekniği olan “buble sort” ile yoğunlaştırarak vereceğiz. 6.6.1.Bubble Sort (Kabarcık Sıralama): “Bubble Sort” tekniği adını şundan alır: Liste elementlerini bellek içinde yukarı doğru (daha yüksek numaralanmış adrese) “yükseltir” Tıpkı havaya yükselen çorba kabarcıkları gibi. Bir bubble sort bir listenin yolu boyunca sıralı olarak çalışır. Birinci elementten başlar ve listenin içindeki her elemanı bir sonrakiyle karşılaştırır. Eğer bubble sort programı en yüksek numaralanmış adresin komşusunda daha büyük bir element bulursa, bu elementleri değiş tokuş eder. Sonra sıradaki iki elementi karşılaştırır. Eğer gerekliyse bunları da değiş tokuş eder ve böyle gider. 286 en son elemana geldiğinde en yüksek değerli element son liste pozisyonuna ”yükseltilmiştir <bubbled-up>” 50 30 30 10 30 40 10 20 40 10 20 30 10 20 40 40 20 50 50 50 Şekil.6.2. Bir bubble sort en büyük sayıları en sona “yükseltir”. 122 Bu algoritmayla sıralamada, işlemci genellikle şekil <5-2 deki basit örnekte gördüğünüz gibi> listenin içinde birkaç geçiş yapar. Burada ilk geçiş 50’yi listenin sonuna “yükseltir”. Ve sonraki iki geçiş 40 ve 30’u sonraki en yüksek konuma yükseltir. Böylelikle bu dikkate değer liste bu üç geçişle sıralanmış olur. Listenin “olaylarını” şekil.6.2’deki gibi geçiş-geçiş görerek., bildiğiniz gibi bir liste tamamen sıralandığında bunu sizin için kolayca yapar, ancak bunu bilgisayar nasıl bilir? Siz özel geçiş değeri vermeden ya da bazı diğer yollar durduğunda söylemeden, bilgisayar rahat bir şekilde geçişten sonra geçişi çalıştırarak sona ulaşır. Sıralama geçişlerinin sayısı listenin başlangıçtaki düzenine bağlıdır. Bir program içinde tam geçiş sayacı desteklemenin bir yoluna sahip değiliz. Bir alternatif olarak, biz bilgisayarın sıralama durduğu zaman anlamak için kullanabileceği değiş tokuş bayrağı adında özel bir göstergeç ayarlayacağız. Değiş tokuş bayrağı her sıralama geçişinden önce 1 olarak ayarlanır. Bir element değiş tokuş işlemi içeren herhangi bir sıralama geçişi bu elementi 0 a dönüştürür. Böylelikle, her geçişten sonra değiş tokuş bayrağının değeri bilgisayarın sıralamaya devam edip etmediğini söyler. Bir listenin içinde başka bir geçiş yapıldığını söyler. Bir 1 ise listenin sıralı olduğunu söyler, ve sıralamayı durdurur. Şekil.6.3, bubble sort algoritmasının akış diyagramını gösterir. Görebildiğiniz gibi, Eğer ki bir liste zaten başlangıçtaki düzende ise, işlemciye bu gerçeği anlamak için bir geçiş yaptırır. Bir geçiş minimum ise, hangi geçişlerin maksimum sayısı sizi bekletebilir. Şekil.6.2’de 5 sayılı bir liste zaten sırlanmıştır.onu artan düzene sokmak için yalnızca üç sıralama geçişi yaptık. Bir sonraki geçiş listenin gerçekten sırlanmış olduğunu sapmaya gerek duyuyor. Diğer dört geçişte aynı şekilde bu saptamaya ihtiyaç duyuyor. Eğer başta liste azalan düzende sıralanmış (en kötü durumda) ise, işlemci liste boyunca 5 geçiş yapacaktır. Dört geçiş veriyi sıralamak için, diğeri ise daha başka sıralama gerekmediğini belirlemek içindir.Bu gözlemde, N elementli liste sırlama için ortalama (N+1)/2 geçişle birden N’e kadar geçiş yapar. 123 BAŞLA DEĞİŞ TOKUŞ BAYRAĞI = 1 N=0 HAYIR ELEMENT N+1 EVET ELELEMENTLER DEĞİŞ TOKUŞ OLUYOR DEĞİŞ TOKUŞ BAYRAĞI = 0 N=N+1 HAYIR LİSTENİN SONU MU? EVET EVET DEĞİŞ TOKUŞ HAYIR BİTİR Şekil.6.3.Bubble Sort Akış Diyagramı 124 6.6.2.Bubble Sort Program: Bubble sort teorisinde geri plan önce gelerek ve bir neler yapılması gerektiğini gösteren akış diyagramı bir sıralama programı yazmak için hazırladık. Örnek.6.4, Word değerlerinin listesini sıralayan bir prosedürü (B_SORT) gösterir. (Kolayca byte’ların listesini sıralayacak şekilde değiştirebilirsiniz). Alışılagelmiş olarak, liste ekstra segmentin içindedir ve başlangıç adresi DI’nın içindedir. B_SORT <BX>’i değiş tokuş bayrağını tutmak için kullanır. (her zaman 1 ya da 0 ‘dan birini içerir). Ax bir listedeki bir sonraki element ile karşılaştırılmış element değerini tutar. B_SORT prosedürü data segmentin içinde iki Word değişkeni kullanır: SAVE_CNT karşılaştırma sayacını tutar (element sayacı -1) ve START_ADDR listenin başlangıç adresini tutar. B_SORT bu değişkenleri her yeni sırlama işleminin başlangıcında CX ve DI’yı yeniden başlangıç durumuna getirmek için kullanır. Her ne kadar B_SORT prosedürü birçok talimat içerse de, oldukça kolaydır. SAVE_CNT ve START_ADDR için değerleri hesapladıktan sonra, prosedür değiş tokuş bayrağını (BX=1), karşılaştırma sayacı (CX), ve element işaretçisi (DI)’yı başlangıç durumuna getirir. NEXT etiketinde 286 elementi AX’in içine yükler, sonra bir bellekteki bir sonraki elementle karşılaştırır. İkinci element birinci elementten daha küçükse, 286 bunu AX’in içine yükler ve bu iki elementi bellekte <ters düzende> saklar. Çünkü bir değiş tokuş yer almıştır. İşlemci BX’i 0 olarak temizler. CONT kısmındaki LOOP talimatı denetimi bütün liste işlenene kadar NEXT’e aktarır. Bütün elementler karşılaştırıldığında, CMP talimatı değiş tokuş bayrağının (BX) sıfır olup olmadığını denetler. Eğer sıfırsa, en düşüğünde değiş tokuş sıralama geçişinin öncellenmesi sırasında yer aldı, bu yüzden 286 yeni bir geçiş yapmak için INIT kısmına geri dallandı. Aksi halde, sıralama geçişinden sonra BX hala 1 ise, liste en sonunda sıralanmıştır. Bu yüzden, 286 Dı’yı START_ADDR’den ve BX ve AX’i stack’ten geri yükler, sonra döner. 6.6.3.Bubble Sort Programını Düzene Koymak: Örnek 5-42teki Bubble Sort prosedürü bir zorluğa, ancak önemli bir eksikliğe sahiptir: bazı elementleri gereksiz yere sıralar. Özel olması için, her sıralama geçişi sırasında B_SORT listedeki her element çiftini karşılaştırır. Not: Ancak her geçişte “yükselmeler” listenin içinde bir elementten son konumadır. Bunda, ilk geçiş en yüksek değeri elementi listenin en sonuna yükseltir., ikinci geçiş bir sonraki en yüksek eğerli elementi sonraki en son konuma yükseltir. Ve böyle gider.. Böylece, listenin sonundaki elementler boyunca elementlerin en son (sıralanmış) konumlarına ulaşılmış olur. Bunları sonradan gelen sırlama geçişlerinden dışlayabilirsiniz. 125 Örnek.6.4: Bubble sort prosedürü: TITLE B_SORT - Bubble Sort ; Ekstra segmentteki listenin 16-bit elementlerini düzenler ; segment artan düzendedir, bubble sort kullanılır. ; Girdiler : ES:DI = Listenin başlangıç adresi İlk bölge = Liste uzunluğu (Word) ; DI değiştirilmemiştir. ; Assemble with: MASM B_SORT; ; Link with: LINK callprog+B_SORT; DSEG SEGMENT PARA ’DATA’ SAVE_CNT DW ? START_ADDR DW ? DSEG ENDS PUBLIC B_SORT CSEG SEGMENT PARA ‘CODE’ ASSUME CS:CSEG,DS:DESG B_SORT PROC FAR PUSH DS ; Cagiran’in registerlarını kaydet PUSH CX PUSH AX PUSH BX MOV AX,DESG ; DS’yi başlangıç durumuna getir MOV DS,AX MOV START_ADDR,DI ; Başlangıç adresini kaydet MOV CX,ES:[DI] DEC CX ; Element sayacını gidip getir ; sayaç-1 karsılaştırmaları için hazır ol MOV SAVE_CNT,CX ; Bu değeri belleğe kaydet INIT: MOV BX,1 ; Değiş tokuş bayrağı (BX) = 1 MOV CX,SAVE_CNT ; Bu sayacı CX’e yükle MOV DI_START_ADDR ; Başlangıç adresini DI’ya yükle NEXT: ADD DI,2 MOV AX,ES:[DI] ; Adres bir veri elementini adresle ; ve bunu AX’e yükle CMP ES:[DI+2],AX ; Sonraki element < bu element? JAE CONT ; Hayır. Yeni cifti denetlemeye git 126 XCHG ES:[DI+2],AX ; Evet. Bu elementleri değiş tokuş et MOV ES:[DI],AX SUB BX,BX CONT: ; ve değiş tokuş bayrağını 0 yap LOOP NEXT CMP BX,0 ; Bütün listeyi isle ; değiş tokuşlar yapıldı mi? ; Eğer yapıldıysa, listeyi yeniden isle JE INIT MOV DI,START_ADDR ; Yapılmadıysa, saklayıcıları yerine koy POP BX POP AX POP CX POP DS RET ; ve çık. B_SORT ENDP CSEG ENDS END Sıralanmış elementleri dışlamak için, liste boyunca her geçiş kendi atasında en az bir karşılaştırma içerecektir. Biz bu olayı Kendi prosedürümüzü değiştirerek yaptık. Ve böylece SAVE_CNT’nin içindeki değer her yeni geçişten önce azalır. Bunu yapmak için, INIT etiketi altındaki azalma sayacı işlemini getirmek için prosedür içindeki altıncı, yedinci ve sekizinci talimatları basitçe değiştirmek gerekir. Siz aynı zamanda azalmadan sonra SAVE_CNT 0 ise işlemciyi çıkar yapmak için bir başka talimat eklemelisiniz. Aşağıda bu değişikliğin özeti vardır. Aslı Düzenlenmiş *** DEC CX MOV SAVE_CNT,CX MOV SAVE_CNT,CX INIT: MOV BX,1 INIT: MOV BX,1 DEC SAVE_CNT JZ SORTED Burada, SORTED MOV talimatı üzerinde START_ADDR’den DI’nın içeriğini geri yükleyen etikettir. Örnek 5-5 bu değişikliğe sahip yeni bir bubble sort prosedürünü (BUBBLE) gösterir. Herhangi bir verilen liste için, BUBBLE Örnek.6.4’teki B_SORT prosedüründeki gibi sıralama geçişlerinin aynı sayılarını işler. Ancak çünkü BUBBLE karşılaştırmaları yaklaşık yarısı kadarını yapar, bu B_SORT’tan daha hızlı çalışır. 127 Örneğin: 100 elementi azalan düzende düzenlenmiş olarak sırlamak için;B_SORT 100 geçiş yapar, ve her geçiş için 99 karşılaştırma – toplam 9,900 karşılaştırma yapar. Tam aksine, BUBBLE 50 karşılaştırmanın ortalaması için 99 karşılaştırmayla ilk geçişi yapar ve bir de son geçişi yapar, - toplam 5,500 karşılaştırma. B_SORT ile BUBBLE’ı karşılaştırmak için, IBM PC AT’de bu iki prosedürü de kullanarak 16bit elementlerin iki listesini sıraladım. Her iki liste de başlangıçta azalan düzende düzenlendi. 500 elementli ilk liste, B_SORT ile 2,5 saniyede; BUBBLE ile 1,5 saniyede sıralandı. 1000 elementli ikinci listenin sırlanması B_SORT ile 10,0 saniye BUBBLE ile 5,0 saniye aldı. Bu testlere dayanarak, BUBBLE bir listeyi B_SORT’tan yüzde 40-50 daha hızlı sıralıyor. Not: Sıralama zamanı uzun listeleri ele aldığımızda üzücü bir şekilde artıyor. Bizim bubble sort prosedürümüz 32K Word’leri sırlayabiliyor, ‘’ancak listeniz bu uzunluğun herhangi bir yerindeyse, daha iyisini hazırlamak için bekleyeceksiniz.’’ “” éé “” Aslında, en kütü durumda 2000 çift kelimenin listesinin sıralanması BUBBLE ile 20 saniye alır. Bu 1000 kelimelik bir listenin sıralanmasının dört katıdır. Örnek.6.5: Daha iyi bir Bubble Sort Prosedürü: TITLE B_SORT - Daha iyi Bubble Sort ; Ekstra segmentteki listenin 16-bit elementlerini düzenler ; segment artan düzendedir, bubble sort kullanılır. ; Girdiler : ES:DI = Listenin başlangıç adresi İlk bölge = Liste uzunluğu (Word) ; DI değiştirilmemiştir. ; Assemble with: MASM BUBBLE; ; Link with: LINK callprog+BUBBLE; DSEG SEGMENT PARA ’DATA’ SAVE_CNT DW ? START_ADDR DW ? DSEG ENDS PUBLIC BUBBLE CSEG SEGMENT PARA ‘CODE’ ASSUME CS:CSEG,DS:DESG BUBBLE PROC FAR PUSH DS ; Çağıranın registerlarını kaydet PUSH CX PUSH AX PUSH BX 128 MOV AX,DESG ; DS’yi başlangıç durumuna getir MOV DS,AX MOV START_ADDR,DI MOV CX,ES:[DI] ; Element sayacını gidip getir MOV SAVE_CNT,CX ; Bu değeri belleğe kaydet INIT: ; Değiş tokuş bayrağı (BX) = 1 MOV BX,1 MOV CX,SAVE_CNT ; Bu sayacı CX’e yükle MOV DI_START_ADDR ; Başlangıç adresini DI’ya yükle NEXT: ADD DI,2 ; Adres bir veri elementini adresle MOV AX,ES:[DI] ; ve bunu AX’e yükle CMP ES:[DI+2],AX ; Sonraki element < bu element? JAE CONT ; Hayır. Yeni cifti denetlemeye git XCHG ES:[DI+2],AX ; Evet. Bu elementleri Değiş tokuş et MOV ES:[DI],AX SUB BX,BX CONT: ; ve Değiş tokuş bayrağını 0 yap LOOP NEXT CMP BX,0 JE INIT ; Bütün listeyi isle ; Değiş tokuşlar yapıldı mi? ; Eğer yapıldıysa, listeyi yeniden isle SORTED: MOV DI,START_ADDR ; Yapılmadıysa, saklayıcılarılar yerine koy POP BX POP AX POP CX POP DS RET ; ve çık. B_SORT ENDP CSEG ENDS END 6.7.Düzenli Listeler: Şimdi bir listenin nasıl sıralanacağı biliyorsunuz. Gelin özel bir değerin nasıl aranacağını tartışalım ve elementleri ekleyeceğimizi ve sileceğimizi görelim. 129 6.7.1.Düzenli Bir Listede Arama Yapma: Düzesiz listeleri anlatırken düzensiz listenin gerektirdiği arama boyunca elementleri element element nasıl yerleştirildiğini öğrendik. Bu N-elementli bir liste için ortalama N/2 karşılaştırma alıyordu. Bir liste düzenliyse, ancak, siz bir değeri bulmak için birkaç arama tekniklerinin herhangi birini kullanabilirsiniz. Hepsi için ancak en kısa listeler için, bütün bu teknikle sıralı aramadan daha hızlı ve daha verimlidir. 6.7.2.Binary(İkili) Arama: Düzenli listelerlerde arama için bir yaygın teknik binary arama (binary search) diye adlandırılır. Bu isim şu gerçeği yansıtır: bu arama listeyi sürekli olarak ikiye bölündüğünü ve sonunda bir bir elementin içinde saklandığını yansıtır. Binary arama listenin ortasından başlar ve aranan değerin bu noktanın üstünde ya da altında olup olmadığını bildirir. Bundan sonra listenin yarısını alır ve bunu ikiye böler, ve böyle sürüp gider. Şekil.6.4’ deki akış diyagramı düzenli liste üzerinde sonuca benzer bir adres üreterek nasıl binary arama yapacağımızı gösterir. Aranan değer listenin içindeyse, adres bu eşleme elementinindir. Eğer aranan değer listenin içinde değilse, adres karşılaştırılanın en son yeridir. Kuşkusuz, bu aramayı gerçekleştiren program aynı zamanda adresin başarılı ya da başarısız aramayı yansıtıp yansıtmadığını söyleyen birkaç çeşit göstergeci de döndürür. Örnek.6.6, işaretsiz Word’lerin düzenli bir listesinde arama yapmakta kullanabileceğiniz bir prosedürü (B_SEARCH) gösterir.gerçekte bu prosedürle Wordlerin yerine byteları gerektirmesi istenirse tamal algoritmamızda birkaç değişiklik yapmamız gerekir. Bir şey için, çünkü Word’ler bellekte iki byte’lık yer ayırır. biz her zaman çift değerler olan ikinin çarpanların indekslemeyi garanti eden talimatlar kullanmalıyız. Aynı nedenle, indeks 2’ye azaldığında (0 yerine) aramayı sonlandırırız ve başarısız olarak tanımlarız. 130 BAŞLA GİTGETİR INDEX’İ (ELEMENT INDEX’İ 2’YE BÖL EVET INDEX = 0? HAYIR ARANAN ADRES = ADRES + INDEX ARANAN DEĞER BULUNDU MU? HAYIR ARANAN DEĞER LİSTENİN EN BÜYÜĞÜ MÜ? EVET HAYIR, KÜÇÜK BİTİR INDEX’İ 2’YE BÖL EVET INDEX = 0? HAYIR ARANAN ADRES = ADRES INDEX Şekil.6.4. Binary Arama Algoritması 131 EVET Örnek.6.6: 16-bit binary arama prosedürü: TITLE B_SEARCH - Binary Arama Prosedürü ; ekstra segmentte bir düzenli listede AX’in içindeki ; Word değeri için arama yapar. ; Girdiler : ES:DI = Listenin Başlangıç adresi İlk bölge = Listenin uzunluğu (Word) ; Sonuçlar: Değer listenin içindeyse, CF = 0 SI = Esleme elementinin ofseti Değer listenin içinde değilse, CF = 1 SI = Son karsılaştırılan elementin ofseti ; AX ve DI etkilenmemiştir. ; Assemble with: MASM B_SEARCH; ; Link with: LINK callprog+B_SEARCH; DSEG SEGMENT PARA ‘DATA’ START_ADDR DW ? DSEG ENDS PUBLIC B_SEARCH CSEG SEGMENT PARA ‘CODE’ ASSUME CS:CSEG,DS:DSEG B_SEARCH PROC FAR PUSH DS ; Cagiranin DSsaklayicilarini kaydet PUSH AX MOV AX,DESG MOV DS,AX ; DS’yi Başlangıç durumuna getir POP AX ; Eğer AX listenin sınırları ötesinde bulunduysa. CMP AX,ES:[DI+2] ; Aranan Değer < or = ilk element? JA CHK_LAST ; Hayır. En son elementi denetlemeye git LEA SI,ES:[DI+2] ; Evet. İlk elementin adresini gidip getir. JE EXIT STC JMP EXIT ; Eğer Değer = ilk element ise, çık ; Eğer Değer < ilk element ise, CF’yi ayarla ; ve sonra çık 132 CHK_LAST: MOV SI,ES:[DI] ; En son elementi işaretle SHL SI,1 ADD SI,DI CMP AX,ES:[SI] ; Aranan Değer en son elementten büyük mu? JB SEARCH ; Hayır. Arama listesine git JE EXIT STC ; Evet. Değer en son elemente eşitse çık ; Değer > en son element, set CF JMP EXIT ; and then exit ; Listenin içindeki değeri arama SEARCH: MOV START_ADDR,DI ; Başlangıç adresini belleğe kaydet MOV SI,ES:[DI] ; Indeks’i hafızadan oku EVEN_IDX: TEST SI,1 ; Indeks’i bir çift değere it JZ ADD_IDX INC SI ADD_IDX: ADD DI,SI ; Bir sonraki arama adresini hesapla COMPARE: CMP AX,ES:[DI] ; Aranan Değer bulundu mu? JE ALL_DONE ; bulunduysa, çık JA HIGHER ; Aksi halde, doğru yarıyı bul ; Bu talimatlar listenin içinde aranan Değer daha küçükse çalışır CMP SI,2 ; Index= 2? JNE IDX_OK NO_MATCH: STC ; Öyleyse, CF’yi ayarla JE ALL_DONE ; ve çık IDX_OK: SHR SI,1 ; değilse, index’i ikiye bol TEST SI,1 ; Indeks’i bir çift değere it JZ SUB,IDX INC SI SUB_IDX: SUB DI,SI ; Bir sonraki adresi hesapla JMP SHORT COMPARE ; Bu elementi denetlemeye git ; Bu talimatlar listenin içinde aranan Değer daha büyükse çalışır HIGHER: CMP SI,2 ; Indeks = 2? JE NO_MATCH SHR SI,1 ; Öyleyse, CF’yi ayarla ve çık ; Değilse, index’i ikiye bol JMP SHORT EVEN_IDX ; Bir sonraki elementi denetlemeye git ; Aşağıdaki talimatlar çıkış talimatlarıdır 133 ALL_DONE: MOV SI,DI ; Karsılaştırma adresini SI’nin içine tası MOV DI,START_ADDR ; Başlangıç adresini yerine koy EXIT: POP DS RET ; ve çık B_SEARCH ENDP CSEG ENDS END Bu prosedürde, aranan değer AX’in içinde ve listenin başlangıç adresi DI’nın içindedir. B_SEARCH sonuç adresini SI’nın içine geri döndürür ve CF değerin bulunup (CF=0) bulunmadığı (CF=1) söyler. B_SEARCH prosedürü temel binary arama algoritmasının göstermediği bir adımla başlar. (Şekil 5-4). Bu aranan değeri listenin ilk ve son elementleriyle karşılaştırır. Aranan değer ilk elementten daha küçükse ya da son elementten daha büyükse ya da bu elementlerden birine eşitse; prosedür daha fazla gürültü patırtı yapmadan sonlanır. Eğer bu başlangıç denetimleri başarısız olursa ancak, 286 arama işlemini SEARCH’ten başlatarak ilerletir. DI’yı belleğe kaydettikten sonra, 286 indeksi (Word sayacı) SI’nın içindeki listenin ilk yerinden kopyalar ve onu çift değere iter.Bu indeks listenin ortasındaki elementin adresinden DI’ya eklenmiştir. Başlangıç değeri binary arama içindir. Sonra 286 aranan değeri ortadaki element ile karşılaştırır. Ve değer eşitse ALL_DONE kısmına dallanır. Eşitliğin olmaması durumunda, 286 listenin üst yarısında (HIGHER kısmında başlayan talimatları kullanarak) ya da alt yarısında aramanın sürüp sürmediğini belirler. Bu yollar aşağıdakileri yaptığınızda benzerdir. 1. Indexin 2’ye eşit olup olmadığını denetle. Eğer öyleyse, 286 CF’yi 1’e ayarlar (Bir eşitsizlik gösterir), sonra ALL_DONE’a aktarır ve çıkar. 2. Index’i bir konum sağa kaydırarak ikiye böl. 3. Kaydırılmış index’i çift değere doğru it. Ancak, listenin düşüğü aramak için, 286 index’i (SI) güncel adresten (DI) çıkarır; yükseği bulmak için index’i güncel adrese ekler. Bu işlem indeks 2’ye kadar azalana ya da aranana değer bulunana kadar yinelenir. Başka yolla, DI SI’ya taşındığında ve DI’nın asıl içeriği bellekten geri alındığında prosedür ALL_DONE’da biter. Binary arama düz sıralı element element aramadan ne kadar verimli – Örnek.6.1 ve 6.2 ‘deki çeşidiyle? Kuşkusuz, siz doğal olarak bir listeyi düzende bir değer için elementi eşleyerek bir şeyler yapmak için ararsınız. Tipik olarak, listeye bir değer eklemek ya da listeden bir değer çıkarmak istersiniz. Şimdi bu işlemleri nasıl gerçekleştirildiğini görelim. 134 6.7.2.1.Düzenli Bir Listeye Bir Element Eklemek: Düzenli bir listeye bu dört adımla bir element ekleyebilirsiniz. 1. Değerin nereye eklenmiş olduğunu bul. 2. Tüm daha yüksek değerli elementleri bir konum aşağı taşıyarak giriş için bölgeyi temizleyin. 3. Yeni boşaltılmış element konumuna girişi ekleyin. 4. Eklemeyi yansıtmak için, element sayacına 1 ekleyin. B_SEARCH prosedürü önceden geliştirilip bize verilmiş iyi bir ipucu olan girişin nereye yapılabileceğini içerir: arama bittiğinde elementin adresi geri döner. Adım 1’i tamamlamak için, son aranan elementin hemen önce ya da hemen sonra girilip girilmediğini belirlememiz gerekir. Bunu giriş değerini son aranan element ile karşılaştırarak belirleriz. Örnek.6.7, bizim listelediğimiz dört adımı gerçekleştiren (ADD_TO_OL) prosedürünü gösterir. Bu B_SEARCH’ü çağırarak giriş değerinin zaten listenin içinde olup olmadığını bulmak için başlar. B_SEARCH’ı yeniden çağırma SI’nın içine bir adres ve Elde Bayrağına’da (CF) bulundu/bulunamadı göstergecini döndürür. B_SEARCH’tan dönen, ADD_TO_OL prosedürü CF’yi sorgular, ve CF 0 ise çıkar (bu girişin zaten listenin içinde olduğu anlamına gelir). CF 1 ise ancak, prosedür en son aranan adresi BX’in içine kaydeder ve en son elementin adresini (CX’in içindeki) hesaplar. SI’nın içeriğinin bu adresten çıkarılması ekleme için bir oda yapmak için bellek içinde daha yükseğe taşınmış olması gereken byte’ların sayısını verir. Bu sonucu 2’ye bölme (sağa kaydırarak) size ne kadar Word’ün taşındığını söyler. Eğer giriş değeri en son karşılaştırılan elementten küçükse, bu element zaten taşınmış olmalıdır, bu yüzden taşıma sayacını (CX) 1 arttırırız. Örnek.6.7: Düzenli Bir Listeye Bir Element Eklemek: TITLE ADD_2_OL - Düzenli listeye girdi ekler ; Düzenli liste içine AX’ten bir değer ekler ; ekstra segment, bu değer listenin içinde Değilse. ; Girdiler : DI = Listenin Başlangıç adresi İlk bölge = Liste uzunluğu (Word) ; Sonuçlar : Yok ; DI ve AX değiştirilmemiştir ; B_SEARCH prosedürü (Örnek 5-6) aramayı sağlamak için kullanıldı ; Assemble with: MASM ADD_2_OL; ; Link with: LINK callprog+ADD_2_OL+B_SEARCH; EXTRN B_SEARCH:FAR PUBLIC ADD_TO_OL 135 CSEG SEGMENT PARA ‘CODE’ ASSUME CS:CSEG ADD_TO_OL PROC FAR PUSH CX ; saklayıcıları Kaydet PUSH SI PUSH BX CALL B_SEARCH JNC GOODBYE MOV BX,SI ; değer lisenin içinde mi? ; Öyleyse çık ; Değilse, Karsılaştırma adresini BX’e kopyala MOV CX,ES:[DI] ; En son elementin adresini bul SHL CX,1 ADD CX,DI ; ve bunu CX’in içine koy PUSH CX ; Bu adresi stack’e kaydet SUB CX,SI ; Tasınmış Word’lerin sayısını hesapla SHR CX,1 CMP AX,ES:[SI] ; Tasınmış elementler karsılaştırılacak mi? JA EXCLUDE INC CX ; Evet. Taşıma sayacı 1 arttır JNZ CHECK_CNT EXCLUDE: ADD BX,2 CHECK_CNT: CMP CX,0 ; Hayır. Girdi göstergecini ayarla ; Taşıma sayacı =0? JNE MOVE_ELS POP SI ; Öyleyse, değeri listenin sonuna sakla MOV ES:[SI+2],AX JMP SHORT INC_CNT ; sonra element sayacı arttırmaya git MOVE_ELS: POP SI PUSH BX ; Taşıma için Başlangıç adresini yükle ; Girdi adresini stack’e kaydet MOVE_ONE: MOV BX,ES[SI] ; Listede bir element aşağı tası MOV ES:[SI+2],BX SUB SI,2 ; Sonraki elementi işaretle LOOP MOVE_ONE POP BX ; Hepsi taşınana kadar yinele ; Girdi adresini geri al MOV ES:[BX],AX ; Listede AX’i gir INC_CNT: INC WORD PTR ES:[DI] ; Element sayacına 1 ekle 136 GOODBYE: POP BX ; saklayıcıları yerine koy POP SI POP CX RET ; ve çık. ADD_TO_OL ENDP CSEG ENDS END CHECK_CNT’de, 286 taşıma sayacını denetler. Eğer sıfırsa, girişi basitçe listenin sonuna çivilenmiştir. Aksi halde, bu değer listenin içine eklenmiş olmalıdır; bu tüm sonradan gelen elementleri Word konumunun aşağısına taşınmasını gerektirir. Bu talimatlar MOVE_ELS’de başlar ve elementleri bir bir en son listenin içindeki Word’den başlayarak aşağı taşımaya gerekli elementler taşınmış olduğunda, 286 girişi (AX) yeni boşaltılmış yuvaya ekler, sonra element sayacını bir artırır. 6.7.2.2.Düzenli Bir Listeden Bir Element Silmek: Düzenli bir listeden bir element silmek eklemekten daha kolaydır. Bütün bu yapmak zorunda olduklarımız uygun elementi bulmak, tüm sıradaki elementleri bir konum yukarı taşımak ve element sayacını azaltmak için. Örnek.6.8, B_SEARCH (Örnek.6.6) kullanarak silme eğilimindeki “hedefi” yerleştiren tipik bir silme prosedürü (DEL_OL)’u gösterir. Alışılagelmiş olarak, listenin başlangıç adresi DI’nın içindedir ve silinmiş olan değer AX’in içindedir. B_SEARCH listenin içine giriş değerini yerleştirir. DEL_OL bunun adresini kullanır, ve listenin sonunun adresi ne kadar Word yukarı taşındığını belirlemek içindir. MOVEM’deki dört-talimatlı döngü taşıma işlemini gerçekleştirir. 286 bütün Word’leri taşıdığında, listenin element sayacını silme eylemini yansıtmak için azaltır. Örnek .6.8: Düzenli Bir Listeden Bir Element Silme: TITLE DEL_OL - Düzenli listeden element siler ; Ekstra segmentteki düzenli liste içinden AX’e bir değer siler ; bu değer listenin içinde ise . ; Girdiler : DI = Listenin Başlangıç adresi İlk bölge = Liste uzunluğu (Word) 137 ; Sonuçlar : Yok ; DI ve AX değiştirilmemiştir ; B_SEARCH prosedürü (Örnek 5-6) aramayı sağlamak için kullanıldı ; Assemble with: MASM DEL_OL; ; Link with: LINK callprog+DEL_OL+B_SEARCH; EXTRN B_SEARCH:FAR PUBLIC DEL_OL CSEG SEGMENT PARA ‘CODE’ ADD_TO_OL PROC FAR ASSUME CS:CSEG PUSH CX ; saklayıcıları Kaydet PUSH SI PUSH BX CALL B_SEARCH JNC ADIOS ; değer lisenin içinde mi? ; Öyleyse çık MOV CX,ES:[DI] ; Öyleyse en son elementin adresini bul SHL CX,1 ADD CX,DI ; ve bunu CX’in içine koy CMP CX,SI ; En son element silinmiş mi? JE CNT_M1 ; Evet. Element sayacını azaltmaya git SUB CX,SI ; Hayır. Taşınma sayacını hesapla SHR CX,1 MOVEM: MOV BX,ES:[SI+2] ; Listede bir element yukarı tası MOV ES:[SI],BX ADD SI,2 ; Sonraki elementi işaretle LOOP MOVEM ; Hepsi taşınana kadar yinele CNT_M1: DEC WORD PTR ES:[DI] ; Element sayacını 1 azalt ADIOS: POP BX ; saklayıcıları yerine koy POP SI POP CX RET ; ve çık. ADEL_OL ENDP CSEG ENDS END 138 6.9.Arama Tabloları: Bazı programlar işlemeye gerek duydukları değerleri tutmak için tabloları kullanırlar. Bazen bu tablolar hesaplaması çok zaman alan sayıları tutar, <sinüs ve açılar gibi>. Diğer zamanlarda, bu tablolar program girdisiyle ilişkili olarak tanımlanmış bazı parametreleri tutar, ancak hesaplamadan tutar. Bu durum için, bilgisayarın isme karşılık gelen telefon numarasını hesaplamasını bekleyemezsiniz. Bunun gibi uygulamalar “arama tabloları” diye adlandırılır. bu ismin ima ettiği gibi, bir arama tablosu bilinen bir değere dayanan (bir işlev) bilginin (bir parça) bir öğesini elde eder. Arama tabloları karmaşık ya da zaman tüketen dönüşüm işlemlerini kaldırabilir. Sayının kare kökünü ya da küp kökünü alması ya da açının (sinüs, kosinüs gibi) türetmek gibi işlevler olabilir.arama tabloları genellikle argümanların küçük aralık kapsadığı bir işlev olduğunda verimlidir. (örneğin: sayıları 1 ile 20 arasında olan küpler). Bir arama tablosu kullanarak, bir değere gereksinim duyduğu her zaman karmaşık hesaplamalar gerçekleştirmeye gerek duymaz. Genelde, arama tabloları hepsinde zaman kazandırır ancak en basit durumlarda, (Örneğin, her zaman işlevin değerini iki kez argümanları saklayan bir arama tablosu kullanamayacaksınız). Ancak arama tabloları boyunca genellikle belleğin saklama boşluğunun değerlerini büyük alır. Bunlar uygulamalarda bellek boşluğunu yürütme hızı için kurban etmek istediğinizde en verimlidir. Çünkü arama uygulamaları çok yaygındır, 286 bu amaç için Translate <dönüştür> (XLAT) adında özel bir talimata sahiptir. XLAT bir byte tablosunda BX’in içeriğini temel adres gibi kullanarak ve AL’nin içeriğini bir indeks gibi kullanarak bir değeri arar ve bunu AL’nin içine geri döndürür. Bu bölüm byte tabloları ve Word tablolarının her ikisi için arama işlemlerinin örneklerini içerir. Arama tablolarında karmaşık eşitlikleri destekleyerek işlem zamanından ve geliştirme zamanından kazanabilirsiniz. Örneğin:, bir arama tablosu bir açı için sinüs ve kosinüsü destekleyebilir. 6.9.1.Bir Açının Sinüsü: Yüksek okuldaki trigonometriden anımsayabileceğiniz gibi, bütün açıların sinüsü 0° ve 360° formunda eğri Şekil.6.5.A’ da gösterilmiştir. Matematiksel olarak, yaklaşık değeri bu denklemle bulabilirsiniz. Sin(X) = X – X3/3! + X5/5! - X7/7! + X9/9! .......... 139 (A) SİNÜS (B) KOSİNÜS ÇÇ=ÇEYREKÇEMBER Şekil.6.5. 0 ile 360 derece arasındaki açıların sinüs ve kosinüsleri. Olası yazılan program bu hesaplamayı yapar, ancak program çalışmak için birkaç milisaniyeye gerek duyacaktır. Eğer sizin uygulamanız çok fazla sinüs eğrisi içeriyorsa, böyle bir program yazmakta zorlanabilesiniz. Ancak bütün uygulamalar açıdan sinüse arama tablosuyla daha iyi servis yapar. Bir uygulama herhangi bir açının 0° ile 360° arasındaki tamsayı değerlerinde açının sinüsünü gerektiriyorsa, tabloda kaç tane sinüs değeri olmalıdır – 360 mı? Hayır, bu tabloyu biz yalnızca 91 açının sinüs değerleri ile oluşturabiliriz – 0° ile 90° arasındaki her açı için bir tane. Bunun nasıl böyle olduğunu anlamak için, Şekil 5-5A’ya yeniden bakın. Eğer çizimin en solundaki çeyreğine (0° ile 90° arasındaki açılar) Çeyrekçember1 dedik, ve bunu gördük: 1. Çeyrek çember 2 içindekilerin sinüsü (91° ile 180° arası) Çeyrekçember1’in “ayna imgesi” dir 2. Çeyrek çember 3 içindekilerin sinüsü (181° ile 270° arası) Çeyrekçember1’in “negatif tersidir” dir 3. Çeyrek çember 4 içindeki sinüsü (271° ile 360° arası) bu Çeyrekçember1’in “negatif tersi - ayna imgesi” dir Bu şu anlama gelir: Çeyrek çember 2,3,4 teki sinüsler basit ilişkilerle Çeyrek çember 1’in içindeki sinüslere taşınabilir. Böylelikle, bir arama tablosunda değerleri Çeyrek çember 1’in içinde sakladıysanız, programınız açıların sinüsünü herhangi bir Çeyrek çemberde bu dönüşümleri yaparak bulabilir. Açı X bunların arasındaysa: değer Al 140 0° ve 90° Sin(X) 91° ve 180° Sin(180 - X) 181° ve 270° Sin(X - 180) 271° ve 360° Sin(360 - X) Bu ilişkiler bize bir açı-sinüs dönüşüm programı için bir akış çizelgesi inşa etmeye izin verir. Bu çizelge, Şekil.6.6’da gösterilmiştir. Burada sinüs işaret ve büyüklük değeri olarak türetilmiştir. Burada, sonucun yüksek düzendeki biti sinüsün işaretini verir (0=pozitif, 1=negatif) ve kalan bitler sinüsün büyüklüğünü verir, bu tam değerdir. Örnek.6.9, FIND_SINE adında açıları AX’eten 0° ile 360° arasında alan ve BX’e bir 16-bit işaret ve büyüklük sinüs değeri geri döndüren bir açıdan-sinüse arama prosedürü vermektedir. Sinüsler SINES arama tablosunun içinde tamsayı olarak saklıdır. Bunları operand gibi kullanmak için 10,000’ e bölmelisiniz. Başlamak için, 286 açının boyutunu denetler. Eğer 181°’den daha küçükse, işlemci SIN_POS’a atlar: aksi halde, işaret saklayıcısının en belirgin bitini (CX) 1 olarak ayarlar. Çünkü sinüs 180°’nin üzerinde negatiftir – ve açıdan 180 çıkarılır.bu çıkarmayı SUB 180, AX talimatıyla gerçekleştirebilirsiniz. Ancak 286 bu formda sunuş yapmaz. Oluşan durumda, biz çıkarma işlemini AX’i reddederek yaptık sonra sonuca 180 ekledik. GET_SIN’deki 4 talimat BX’e açıyı yükler, bir Word indeks formunda bunları çiftler, aramada sinüs SINE’nin içindedir, ve bunu CX’in içindeki işaret ile OR işlemine tabi tutar. 141 BAŞLA İŞARET = 0 EVET AÇI <181? HAYIR İŞARET = 1 AÇI = AÇI -180 EVET AÇI <91? HAYIR AÇI = 180-AÇI SİNÜSÜ ARAMA İŞARET EKLE BİTİR Şekil.6.6. açıdan sinüse dönüştürme programı akış çizelgesi. Örnek.6.9: Açının sinüsünün aranması (Look up) TITLE SINE - Açının sinüsü ; Açının sinüsünü dondurur ; Girdiler : AX : Açı (0 - 360) ; Sonuçlar : BX : sinüs, işaret ve büyüklük biçiminde ; AX değiştirilmemiştir ; Assemble with: MASM SINE; ; Link with: LINK callprog+SINE; DSEG SEGMENT PARA ‘DATA’ 142 SINES DW 0,175,349,523,698,872 ; 0-5 DW 1045,1219,1392,1564,1736 ; 6-10 DW 1908,2079,2250,2419,2588 ; 11-15 DW 2756,2924,3090,3256,3420 ; 16-20 DW 3584,3746,3907,4067,4226 ; 21-25 DW 4384,4540,4695,4848,5000 ; 26-30 DW 5150,5299,5456,5592,5736 ; 31-35 DW 5878,6018,6157,6293,6428 ; 36-40 DW 6561,6691,6820,6947,7071 ; 41-45 DW 7193,7313,7431,7547,7660 ; 46-50 DW 7771,7880,7986,8090,8191 ; 51-55 DW 8290,8387,8480,8572,8660 ; 56-60 DW 8746,8829,8910,8988,9063 ; 61-65 DW 9135,9205,9272,9336,9397 ; 66-70 DW 9455,9511,9563,9816,9848 ; 71-75 DW 9703,9744,9781,9816,9848 ; 76-80 DW 9877,9903,9926,9945,9962 ; 81-85 DW 9976,9986,9994,9998,10000 ; 36-40 DSEG ENDS PUBLIC FIND_SINE CSEG SEGMENT PARA ‘CODE’ ASSUME CS:CSEG,DS:DSEG FIND_SINE PROC FAR PUSH DS ; saklayıcıları kaydet PUSH AX PUSH CX MOV BX,DSEG ; DS’yi Başlangıç durumuna getir MOV DS,BX SUB CX,CX ; İşareti 0’la CMP AX,181 ; Açı < 181 derece? JB SIN_POS MOV CX,8000H SUB AX,180 SIN_POS: CMP AX,91 ; Evet. İşaret 0’la devam et ; Hayır. İşareti 1 yap ; Açıdan 180 çıkar ; Açı < 91 derece? 143 JB GET_SIN ; Evet. sinüs aramaya git NEG AX ; Hayır. Açıdan 180 çıkar ADD AX,180 GET_SIN: MOV BX,AX ; Açıyı bir Word index’i yap SHL BX,1 MOV BX,SINES[BX] ; ve sinüs değerini ara OR BX,CX ; sinüsü işaret bit’iyle birleştir POP CX POP AX POP DS RET ; ve çık FIND_SINE ENDP CSEG ENDS END 6.9.2.Açının Kosinüsü: Şekil.6.5.B’de gösterildiği gibi kosinüs eğrisi sinüs eğrisinin bir çeyrek çember sola kaydırılmasından başka bir şey değil. Böylelikle, herhangi bir verilen açının kosinüsü 90° daha büyük açının sinüsüne eşittir. Böyle: cos(X) = sin(X+90) bunu bilerek, Örnek 5-9’deki SINES tablosunu bir açının kosinüsünü bulmak için sinüsünü bulmak kadar iyi kullanabiliriz.Örnek 5-10 bunu yapan bir prosedürü gösterir.FIND_SINE’deki gibi, FIND_COS’un sonucunu 10,000’e bölmelisiniz. Tesadüfi olarak, sinüs ve kosinüs eğrileri dikey eksende simetriktirler; böylece, negatif açıların sinüs ve kosinüsleri pozitif karşıtlarıyla aynı büyüklüklere sahiptir. Örneğin:, -25°’in sinüsü ve kosinüsü +25°’ninkiyle aynı büyüklüktedir. Bu şu anlama gelir; -1° ile -360° arasındaki açılar için eğer ‘AX’in içindeki kedin değerleri destekliyorsa FIND_SINE ve FIND_COS’u zaten kullanabiliyorsunuz. 144 Örnek.6.10: Açının kosinüsünü arama (Look up) TITLE COSINE - Açının kosinüsü ; Açının kosinüsünü dondurur ; Girdiler : AX : Açı (0 - 360) ; Sonuçlar : BX : kosinüs, işaret ve büyüklük biçiminde ; AX değiştirilmemiştir ; FIND_SINE (Örnek 5-9) prosedürü çağrılır ; Assemble with: MASM COSINE; ; Link with: LINK callprog+COSINE+SINE; EXTRN FIND_SINE:FAR PUBLIC FIND_COS CSEG SEGMENT PARA ‘CODE’ ASSUME CS:CSEG, FIND_COS PROC FAR PUSH AX ADD AX,90 ; FIND_SINE ile kullanmak için 90 ekle CMP AX,360 ; Sonuç > 360? JNA GET_COS SUB AX,360 ; Öyleyse, 360 çıkar GET_COS: CALL FIND_SINE ; Kosinüs arama POP AX RET FIND_COS ENDP CSEG ENDS END 6.9.3.Arama Tabloları Kod Dönüşümlerini Gerçekleştirme: Arama tabloları görüntü kodları gibi data kodlarını, printer kodlarını ve mesajları da tutabilir. Örnek.6.11, çoklu arama gerçekleştiren bir prosedürü göstermektedir. Bu AL’deki hexadesimal sayıyı ASCII, BCD, EBCDIC eşitine çevirir ve bunları sırasıyla CH,CL ve AH’in içine geri döndürür.Veriyi bilgisayar ve sistemdeki yazıcı, görüntü aygıtı ya da bazı diğer çevre aygıtları arasında veri gönderdiğinizde, bunarı ASCII (American Standart Code for Information Interchange) formunda alır. EBCDIC (Extended Binary-Coded Decimal Interchange Code) veri işleme ve haberleşme sistemleri için bir iletim protokolüdür. 145 Örnek.6.11: Bir hex sayıyı ASCII, BCD ve EBCDIC ‘ye çevirir. TITLE CONV_HEX - Hex’i ASCII, BCD, EBCDIC’çevirir ; Bir hexadesimal sayıyı onun ASCII, BCD, EBCDIC eşitine çevirir ; Girdiler : AL : Hex sayı ; Sonuçlar : CH = ASCII karakter CL = BCD sayı AH = EBCDIC karakter ; AL değiştirilmemiştir ; Assemble with: MASM CONV_HEX; ; Link with: LINK callprog+CONV_HEX; DSEG SEGMENT PARA ‘DATA’ ASCII DB ‘0123456789ABCDEF’ BCD DB 0,1,2,3,4,5,6,7,8,9,10H,11H,12H,13H,14H,15H EBCDIC DB 0F0H,0F1H,0F2H,0F3H,0F4H,0F5H,0F6H,0F7H DB 0F8H,0F9H,0C1H,0C2H,0C3H,0C4H,0C5H,0C6H DSEG ENDS PUBLIC CONV_HEX CSEG SEGMENT PARA ‘CODE’ ASSUME CS:CSEG,DS:DSEG CONV_HEX PROC FAR PUSH DS ; Sklayicilari kaydet PUSH BX PUSH DX MOV BX,DSEG ; DS’yi Başlangıç durumuna getir MOV DS,BX MOV DL,AL ; Girdi değerini DL’nin içine kaydet LEA BX,ASCII ; ASCII değeri ara XLAT ASCII MOV CH,AL ; ve bunu CH’in içine yükle MOV AL,DL LEA BX,BCD ; BCD değeri ara XLAT BCD MOV CL,AL ; ve bunu CL’in içine yükle 146 MOV AL,DL LEA BX,EBCDIC XLAT EBCDIC ; EBCDIC değeri ara ; ve bunu AH’in içine yükle MOV AH,AL MOV AL,DL ; ve bunu AH’in içine yükle POP DX ; saklayıcıları yerine koy POP BX POP DS RET ; ve çık CONV_HEX ENDP CSEG ENDS END 6.9.4.Dallanma Tabloları: Bazı arama tabloları veri değerlerinden daha çok adresleri içeririler. Örneğin: bir hata rutini olası mesaj setinin içinde dikkate değer bir mesajın adresini bulmak için bir arama tablosu kullanabilir. Benzer bir şekilde, bir kesme servis rutini dikkate değer bir aygıt gerektiğinde servisin tipine bağlı olarak birkaç kesme tutucu programlarında birini çağırmak için bir arama tablosu kullanabilir. Bir başka rutin bir kullanıcının menüdeki hangi seçeneği seçtiğine bağlı olarak birkaç altprogramdan birini çağırmak için bir arama tablosu kullanabilir. Bütün bu uygulamalarda (ve daha fazlasında), arama tablosunun tuttuğu adres dallanma tablosu diye adlandırır. Örnek.6.12, bir bilgisayar yardımlı eğitim programı içinde görebileceğiniz dallanma tablosu uygulamasını gösterir. Bu prosedür, SEL OPT, ADDITION, SUBTRACTION, MULTIPLICATION ya da DIVISION rutinlerini bir öğrencinin menüden 0,1,2 ya da 3 seçip seçmediğine bağlı olarak aktarım yapar. SEL_OPT girilen kodun geçerli olup olmadığını denetler, ve eğer 3’ten büyükse hata raporlama rutinine dallanır. A SEL_OPT’un uygun rutine dolaylı dallanma yapmak için kullandığı bir indeks olursa geçerli bir koddur. Kullanıcı bitirdiğinde, rutinin RET talimatı denetimi programın SEL_OPT kısmına geri döndürür. Bu durumda bir menü görüntülenir. 147 Örnek.6.12: Çoklu Seçenek Seçin Prosedürü: ; Bu prosedür kullanıcının seçtiği AL içindeki koda göre dört ; yordamdan (routine) birini çalıştırır. ; AX ve DI’nin içeriği değiştirilmiştir. ; Bu adres tablosunu data segmentin içine sakla CHOICE DW ADDITION,SUBTRACTION,MULTIPLICATION,DIVISION ; Secim prosedürü burada SEL_OPT PROC FAR CMP AL,3 ; Geçersiz secim? JA ERROR CBW ; Hayır. Kodu Word’e cevir, MOV DI,AX SHL DI,1 ; sonra kodu DI’nin içine tası ; ve bir index’e dönüştür JMP CHOICE[DI] ; Seçilen yordama dallan ERROR: ... ... RET ADDITION: ... ... RET SUBTRACTION: ... ... RET MULTIPLICATION ... ... RET DIVISION ... ... RET SEL_OPT ENDP 148 6.10.Metin Dosyaları: Önceki bölümde veri yapılarının içerdiği sayılarla çalışmıştık. Ancak, kelime işlemci ve diğer uygulamalar, sayısal olmayan bilginin işlenmesini içerir – öncelikle netin dosyalarını. Metin dosyaları ASCII karakterler stringlerini listeler. Örneğin: Bir şirket için Personel bilgilerini tutan bir metin dosyası her personel için bir element ya da kayıt içerecektir. Döngü içinde, her kayıt çalışanların isimlerini, kimlik numaralarını,değişimi, maaş oranını ve bunun gibi şeyleri listeleyen birkaç alt kayda ya da alana sahiptir. String talimatları dikkate değer bir şekilde metin dosyaları üretmek için uygundur. Metin dosyalarını sayısal dosyalar için uyguladığınız aynı basit tekniklerle üretebilirsiniz. Ancak, yapının çoklu kaydından dolayı, metin dosyalarını işleyen programlar basit byte ya da Word işleyenlerden biraz farklı olabilir. Örneğin, Bir metin dosyası aramak genellikle her girişin bir kısmını (belki de yalnız isim kısmını) aranan değerle karşılaştırmayı gerektirir. Bu tün girişi karşılaştırmaktan daha iyidir. Benzer bir şekilde, kabarcık sırlamada bir metin dosyası bitişik girişlerin tek alanını karşılaştırır, ancak bir değiş tokuş gerektiğinde tüm girişler taşınır. Metin dosyası operasyonunun basit bir örneğinde olduğu gibi, isimlerin ve telefon numaralarının bir listesini sıralayan bir programa bakalım. Listenin ilk bölgesi girişin sayacı olan bir “iki-byte” tutar. Listedeki her giriş 42-byte uzunluğundadır ve üç alana bölünmüştür: bir 15-byte’lın sayısını, bir 15-byte’lık ilk/orta isim ve 12-byte’lık telefon numarası. Bir alanda bazı kullanılmayan byte’lar ASCII ‘boş (blank)’ karakter içerdiği varsayılır. Böylece, Listede tipik bir giriş buna benzer: DB ‘CORNELL’,8 DUP (‘ ’) DB ‘RAY’,12 DUP (‘ ’) DB ‘728-732-8437’ (Kuşkusuz, siz doğal olarak klavye yardımıyla yazarak inşa ediyorsunuz. Şimdi ise, bellekte zaten var olan bir dosyayı varsayalım.) Örnek.6.13, ekstra segmentin içinde sıralı telefon listesini bubble-sort ile sıralayan PHONE_NOS prosedürünü göstermektedir. Bunun yapısı Örnek.6.5’deki BUBBLE prosedürüne benzemektedir. (NOT: PUSHA ve POPA’nın kullanımı genel saklayıcıları korumak içindir. Bu talimatlar 80286 için tek olduğu sürece, bu prosedürü IBM PC’de ya da diğer 8086 ya da 8086 tabanlı bilgisayarda çalıştırmak için bu talimatları PUSH’lara ve POP’lara dönüştürmelisiniz.) 149 Örnek.6.13: Bir Telefon Listenin Sıralanması: TITLE PHONE_# - Bir telefon listesini sırala ; Bu prosedür bir telefon listesini alfabetik olarak sıralar ; Liste kişisel girişleri izleyen giriş sayaç Word’lerinden oluşur ; Her giriş 42 byte uzunluğundadır ve uç alana bölünmüştür: ; soyad (15 byte), iki ad (15 byte) ve telefon numarası (12 byte). ; Input: ES:DI = Girdi sayaç Word’ünün adresi ; Assemble with: MASM PHONE_#; ; Link with: LINK callprog+PHONE_#; .286c DSEG SEGMENT PARA ’DATA’ SAVE_CNT DW ? FIRST_ENT DW ? DSEG ENDS PUBLIC PHONE_NOS CSEG SEGMENT PARA ‘CODE’ ASSUME CS:CSEG,DS:DESG PHONE_NOS PROC FAR PUSHA MOV AX,DSEG ; DS’yi Başlangıç durumuna getir MOV DS,AX CLD MOV CX,ES:[DI] ; Element sayacını hafızadan oku MOV SAVE_CNT,CX ; Bu değeri belleğe kaydet ADD DI,2 ; İlk girdinin adresini al MOV FIRST_ENT,DX ; ve bu değeri belleğe kaydet INIT: MOV BX,1 DEC SAVE_CNT JZ SORTED ; Değiş tokuş bayrağı (BX) = 1 ; sayaç-1 karşılaştırması için hazır ol ; SAVE_CNT 0 ise çık MOV CX,SAVE_CNT ; Karsılaştırma sayacını CX’e yükle MOV BP,FIRST_ENT ; ve ilk girdi adresi BP’nin içinde 150 NEXT: MOV DI,BP MOV SI,BP ; bir girdi DI ile adresleniyor ; ve sonraki girdi SI ile ADD SI,42 PUSH CX ; Güncel Karsılaştırma sayacını kaydet MOV CX,15 REPE ; 15-byte soyad’i karşılaştır CMPS ES:BYTE PTR[SI],ES:[DI] ; sonraki soyad < bu soyad? JAE CONT ; Hayır. Sonraki cifti denetlemeye git MOV CX,42 ; Evet. Bu girdileri Değiş tokuş et SWAPEM: MOV AL,ES:[BP] XCHG ES:[BP+42],AL INC ES:[BP],AL INC BP LOOP SWAPEM ; Değiş tokuş bayrağını = 0 yap SUB BX,BX CONT: POP CX ; Karsılaştırma sayacını geri yükle LOOP NEXT ; sonraki iki adi karsılaştırmaya git CMP BX,0 ; Değiş tokuşlar yapıldı mi? JE INIT ; Eğer yapıldıysa, bir diğer geçiş yap SORTED: POPA RET ; Yapılmadıysa, saklayıcıları yükle ; ve çık PHONE_NOS ENDP CSEG ENDS END Başlamak için, prosedür giriş sayacını ve iki değişkenin içinden ilk girişin adresini okur, SAVE_CNT ve FIRST_ENT. Talimat NEXT ve SWAPEM arasında CMPS işlemini ayarlar ve çalıştırır. Burada,bu alanlar belleğin içinde ayrı olarak 42-byte yer kapladığı yerde, DI noktaları bir girişin soy isim alanına, SI noktaları yeni girişin soy isim alanına yüklenir. SWAPEM’deki döngü gerektiğinde iki girişi değiş tokuş eder. Girişler 42-byte uzunluğunda olduğundan bu yana, döngü sayacı CX 42’ye başlangıç durumuna getirilmiştir. Prosedürün kalanı Örnek 5-5 le benzerdir. Not: PHONE_NOS çift soy isimleri hesaplayamaz. Birinin bulunması üzerine, ilk olarak bu girişlerin isim alanlarına bakar ve ikinci olarak bunları alfabetik düzende sıralar. Örnek 5-132ü bunu yaparak değiştirebilirsiniz. 151 EK.1:ASSEMBLER KOMUTLARININ LİSTESİ AAA - Ascii Adjust for Addition ( ASCII Toplama İçin Ayarla ) Kullanım : AAA Değiştirdiği Bayraklar: AF CF (OF,PF,SF,ZF tanımsız) AL nin içeriğini geçerli bir ondalık sayıya çevirir. Yüksek değerli dörtlüğü sıfırlar. operandlar Saat Darbesi Büyüklük (Byte) yok 8 1 AAD -Ascii Adjust for Division ( ASCII Bölme İçin Ayarla ) Kullanım: AAD Değiştirdiği Bayraklar: SF ZF PF (AF,CF,OF tanımsız) Ondalık sayıların bölünmesinden önce kullanılır.AH 'ı 10 ile çarpar ve sonucu AL 'ye ekler. AH'ı sıfırlar. operandlar Saat Darbesi Büyüklük (Byte) yok 60 2 AAM- Ascii Adjust for Multiplication ( ASCII Çarpma İçin Ayarla ) Kullanım : AAM Değiştirdiği Bayraklar:PF SF ZF (AF,CF,OF tanımsız) İki ondalık sayının çarpılmasından sonra kullanılır.Bu komut kullanılmadan önce her byte'ın yüksek değerlikli dörtlüğü sıfırlanmış olması gerekir. operandlar Saat Darbesi Büyüklük (Byte) yok 83 2 AAS- Ascii Adjust for Substraction ( ASCII çıkartma için ayarlar ) Kullanım: AAS Değiştirdiği Bayraklar: AF CF(OF,PF,SF,ZF tanımsız) AL içindeki ,önceki ondalık sayı çıkartmasının sonucunu düzeltir. Yüksek değerlikli dörtlük'ü sıfırlar. operandlar Saat Darbesi Büyüklük (Byte) yok 8 1 ADC -Add with Carry ( Eldeli Toplama ) Kullanım : ADC hedef,kaynak Değiştirdiği Bayraklar:AF CF OF SF PF ZF İki binary operandı toplayarak sonucu hedefe yerleştirir. Eğer CF =1 ise , hedefe 1 eklenir. operandlar Büyüklük (Byte) reg,reg 2 hafıza,reg 2-4 reg,hafıza 2-4 reg,öncel 3-4 hafıza,öncel 3-6 accum-öncel 2-3 ADD -Arithmetic Addition ( Aritmetik Toplama ) Kullanım: ADD hedef,kaynak Değiştirdiği bayraklar: AF CF OF PF SF ZF Hedefi, kaynağa ekler ve hedefin orijinal içeriğiyle değiştirir. İki operand da binary dir. operandlar Büyüklük (Byte) reg,reg 2 152 hafıza,reg reg,hafıza reg,öncel hafıza,öncel accum,öncel 2-4 2-4 3-4 3-6 2-3 AND -Logical And ( Mantıksal Ve ) Kullanım : AND hedef, kaynak Değiştirdiği Bayraklar:CF OF PF SF ZF (AF tanımsız) İki operanda, mantıksal ve işlemi gerçekleştirerek hedefi sonuçla değiştirir. operandlar Büyüklük (Byte) reg,reg 2 hafıza,reg 2-4 reg,hafıza 2-4 reg,öncel 3-4 hafıza,öncel 3-6 accum,öncel 2-3 CALL-Procedure Call ( Alt Program Çağır ) Kullanım: CALL hedef Değiştirdiği Bayraklar:hiçbiri IP'ı (komut göstergeci) yığın'a iterek , hedef adresi IP ye yükler. Kod CS:IP de görevine devam eder. operandlar rel16 (near,IPbağıl) reg16(near,register dolaylı) ptr16:16 (far,fullptr) m16:16 (far,dolaylı) CBW -Convert Byte to Word ( Byte'ı Word'e Değiştir ) Kullanım:CBW Değiştirdiği Bayraklar:hiçbiri AL nin işaretini AH registerina doğru genişleterek ; AL içindeki byte'ı , AX içinde word'e çevirir. Saat Darbesi Büyüklük (Byte) operandlar yok 2 1 CLC -Clear Carry ( Elde'i Sil ) Kullanım : CLC Değiştirdiği Bayraklar: CF Elde (CF=0) bayrağını temizler. operandlar Saat Darbesi Büyüklük (Byte) yok 2 1 CLD-ClearDirectionFlag ( Yön Bayrağını Sil ) Kullanım: CLD Değiştirdiği Bayraklar: DF Yön bayrağını temizleyerek (DF=0) karakter katarı komutlarının; SI ve DI index registerlarının içeriğinin arttırmasına neden olur. operandlar Saat Darbesi Büyüklük (Byte) yok 2 1 CLI-Clear Interrupt Flag (disable) (Kesilim Bayrağını Sil)(engelle) 153 Kullanım: CLI Değiştirdiği Bayraklar: IF Kesilim bayrağını temizleyerek (IF=0) maskelenebilir donanım interruptlarını engeller. NMI ve yazılım interruptları engellenemez. operandlar Saat Darbesi Büyüklük (Byte) yok 2 1 CMC -Complement Carry Flag (Elde Bayrağının Tersini Al ) Kullanım: CMC Değiştirdiği Bayraklar: CF Elde bayrağını tersyüz eder. operandlar Saat Darbesi Büyüklük (Byte) yok 2 1 CMP -Compare ( Karşılaştır ) Kullanım: CMP hedef,kaynak Değiştirdiği Bayraklar:AF CF OF PF SF ZF Hedeften kaynağı çıkarır ve bayrakları günceller fakat sonucu saklamaz.Bayraklar sonradan durumlarına göre kontrol edilir. operandlar Büyüklük (Byte) reg,reg 2 hafıza,reg 2-4 reg,hafıza 2-4 reg,öncel 3-4 hafıza,öncel 3-6 accum,öncel 4 CMPS -Compare String ( Karakter Katarlarını Karşılaştır ) Kullanım: CMPS hedef,kaynak CMPSB CMPSW Değiştirdiği Bayraklar:AF CF OF PF SF ZF Hedefin değerini kaynaktan sonuçları saklamadan, çıkartır.Çıkartmaya dayalı bayrakları güncellenir ve yön ( D ) bayrağını durumuna göre SI ve DI index registerları azaltılır yada arttırılır. CMPSB index registerlarını 1 arttırır/azaltır , CMPSW 2 arttırır/azaltır, CMPSD 4 arttırır/azaltır. Bütün data parçaları işlerken REP öneki kullanılabilir. operandlar Saat Darbesi Büyüklük (Byte) hedef,kaynak 22 1 CWD-Convert Word to Double word ( Word’ü iki Word’ e Çevir ) Kullanım: CWD Değiştirdiği Bayraklar: hiçbiri AX registeri içindeki wordün işaretini DX registerina doğru genişleterek, DX:AX içinde bir doubleword değer oluşturur. operandlar Saat Darbesi Büyüklük (Byte) yok 5 1 154 DAA -Decimal Adjust for Addition ( Ondalık Toplama İçin Ayarla ) Kullanım: DAA Değiştirdiği Bayraklar:AF CF ĞF SF ZF (OF tanımsız) (AL nin içindeki) önceki BCD toplama işleminin sonuç değerini düzeltir. AL nin içeriği bir ondalık sayıya çevirilir. Saat Darbesi Büyüklük (Byte) operandlar yok 4 1 DAS- Decimal Adjust for Substraction ( Ondalık Çıkarma İçin Ayarla ) Kullanım: DAS Değiştirdiği Bayraklar:AF CF PF SF ZF (OF tanımsız) (AL nin içindeki) önceki BCD çıkartma işleminin sonuç değerini düzeltir. AL nin içeriği bir ondalık sayıya çevirilir. operandlar Saat Darbesi Büyüklük (Byte) yok 4 1 DEC- Decrement ( Arttırma) Kullanım: DEC hedef Değiştirdiği Bayraklar: AF OF PF SF ZF Hedefin içeriği bir çıkartılır. operandlar Büyüklük (Byte) reg8 2 hafıza 2-4 reg16 1 DIV -Divide ( Böl ) Kullanımı : DIV kaynak Değiştirdiği Bayraklar : (AF,CF,OF,PF,SF,ZF tanımsız) Accumulator'ün kaynağa işaretsiz binary bölme işlemi. Eğer kaynak (operand)bölen byte değerdeyse , AX kaynağa bölünür ve bölüm AL'ye ,kalan AH'a yerleştirilir. Eğer kaynak (operand) bölen bir word değerse , DX:AX kaynağa bölünür ve bölüm AX de, kalan DX de saklanır. Büyüklük (Byte) operandlar reg8 2 reg16 2 hafıza8 2 hafıza16 2-4 ESC -Escape Kullanım: ESC öncel,kaynak Değiştirdiği Bayraklar: Hiçbiri Matematik işlemciler için data bus'a erişim sağlar. CPU buna NOP gibi davranır fakat hafıza operandını bus'a yerleştirir. operandlar Saat Darbesi Büyüklük (Byte) öncel,reg 2 2 HLT-Halt CPU ( Dur ) Kullanım: HLT Değiştirdiği Bayraklar: Hiçbiri RESET satırı aktif olana kadar bilgisayarı durdurur,NMI ve maskelenebilir kesilim alınır.CPU etkin olmamaya başlar fakat ,daha sonra restart için, o anki CS:IP değerini tutar. operandlar Saat Darbesi Büyüklük (Byte) 155 yok 2 1 IDIV- Signed Integer Division (İşaretli Tamsayılı bölme ) Kullanımı: IDIV kaynak Değiştirdiği Bayraklar:(AF,CF,OF,PF,SF,ZF tanımsız) Akümülatörün kaynağa ,işaretli binary bölümü. Eğer kaynak bir byte değerse , AX kaynağa bölünür ve bölüm AL de kalan AH da saklanır. Eğer kaynak bir word değerse ,DX:AX kaynağa bölünür ve bölüm AL de kalan DX de saklanır. operandlar Büyüklük (Byte) reg8 2 reg16 2 hafıza8 2-4 hafıza16 2-4 IMUL- Signed Multiply ( İşaretli Çarpma) Kullanım: IMUL kaynak Değiştirdiği bayraklar: CF OF ( AF,PF,SF,ZF tanımsız) Akümülatörün kaynakla ,işaretli çarpma işlemi,sonuç akümülatörde saklanır. Eğer kaynak operand bir byte değer ise ,AL ile çarpılır ve sonuç AX de saklanır.Eğer kaynak operand bir word değer ise; AX ile çarpılır ve sonuç DX:AX de saklanır. operandlar Saat Darbesi Büyüklük (Byte) reg8 80-98 2 reg16 128-154 2 hafıza8 86-104 2-4 hafıza16 134-160 2-4 IN -Input Byte or Word From Port ( Port’dan Byte veya Word Oku) Kullanım: IN accum,port Değiştirdiği Bayraklar:hiçbiri Bir byte, veya word port’tan okunarak sırayla AL,veya AX 'e yerleştirilir.Eğer port numarası 0255 arasında ise öncel olarak belirtilebilir, aksi takdirde port numarası DX içinde belirtilmelidir. PC de geçerli port numaraları 0-1024 dür, 65535'e kadar olan değerler üçüncü parti üreticiler ve PS/2 ler tarafından belirtilebilir ve tanınabilir. operandlar Saat Darbesi Büyüklük (Byte) accum,öncel8 10/14 2 accum,DX 8/12 1 INC- Increment ( Arttır ) Kullanım: INC hedef Değiştirdiği Bayraklar: AF OF PF SF ZF Hedef işaretsiz binary operanda 1 ekler. operandlar Büyüklük (Byte) reg8 2 reg16 1 hafıza 2-4 INT-Interrupt ( Kesilim ) Kullanım: INT sayı Değiştirdiği Bayraklar: TF IF 156 Bayrakları iterek ,trap(kapan) ve kesilim bayraklarını temizleyerek (TF=0, IF=0) , yazılım kesilimini başlatır. CS nin itilmesini IP takip eder ve interrupt vektör tablosundan bulunan değer CS:IP 'ye yüklenir.Daha sonra yeni CS:IP tarafından adreslenen yeni konumdan uygulama başlar. operandlar Saat Darbesi Büyüklük (Byte) 3(sabit) 52/72 2 öncel8 51/71 1 INTO -Interrupt on Overflow ( Taşma Olursa Kesilime Git ) Kullanım: INTO Değiştirdiği Bayraklar: IF TF Eğer overflow (taşma) bayrağı O=1 ise bu komut INT 4 üretir. Bu 0000:0010 tan adreslenen kodun uygulanmasını sağlar. operandlar Saat Darbesi Büyüklük (Byte) Etiket:Dallan 53/73 1 Dallanma yok 4 IRET/IRETD -Interrupt Return ( Kesilimden Deri Dön ) Kullanım: IRET Değiştirdiği Bayraklar: AF CF DF IF PF SF TF ZF IP,CS yi ve sonra yığındaki bayrakları çekerek kesilimin kontrol noktasına geridöner ve bu noktadan uygulamaya devam eder. Saat Darbesi Büyüklük (Byte) operandlar iret 32/44 1 JA/JNBE -Jump Above / Jump not below or equal ( Üstünde / Altında veya Eşit Değilse Dallan ) Kullanım: JA etiket JNBE etiket Değiştirdiği Bayraklar: Hiçbiri Eğer Elde bayrağı ve sıfır bayrağının ikisi de sıfırsa ( CF=0, ZF=0) uygulamanın etikete dallanmasına neden olur. İşaretsiz karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JAE/JNB-JumpAbove or Equal / Jump on not below (Üstünde veya Eşit /Altında Değilse Dallan ) Kullanım: JAE etiket JNB etiket Değiştirdiği Bayraklar:hiçbiri Eğer Elde ( CF=0) bayrağı sıfırsa uygulamanın etikete dallanmasına neden olur.Fonksiyonel olarak JNC ye benzer.İşaretsiz karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JB/JNAE-Jump Below / Jump not Above or Equal (Altında / Üstünde veya Eşit Değilse Dallan ) Kullanım: JB etiket 157 JNAE etiket Değiştirdiği Bayraklar: hiçbiri Elde bayrağı ( CF=1) ise ,uygulamanın etikete dallanmasına neden olur. Fonksiyonel olarak JC ye benzer. İşaretsiz karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JBE/JNA -Jump Below or Equal / Jump Not Above (Altında veya Eşit / Üstünde Değilse Dallan ) Kullanım: JBE etiket JNA etiket Değiştirdiği Bayraklar: hiçbiri Elde bayrağı veya Sıfır bayrağı (CF=1 veya ZF=1) ise uygulamanın etikete dallanmasına neden olur. İşaretsiz karşılaştırma operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JC –Jump on Carry (Elde ise Dallan ) Kullanım: Jc etiket Elde bayrağı bir (CF=1) ise uygulamanın etikete dallanmasına neden olur. İşaretsiz karşılaştırma operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JCXZ -Jump if Register CX is Zero ( Cx Registeri Sıfır İse Dallan ) Kullanım: JCXZ etiket Değiştirdiği Bayraklar:hiçbiri Eğer CX registeri sıfırsa uygulamanın etikete dallanmasına neden olur. İşaretsiz karşılaştırma. operandlar Saat Darbesi etiket: Dallan 18 Dallanma yok 6 Büyüklük (Byte) 2 JE/JZ -Jump Equal / Jump Zero ( Eşitse / Sıfırsa Dallan ) Kullanım: JE etiket JZ etiket Değiştirdiği Bayraklar:hiçbiri Eğer sıfır bayrağı (ZF=1) ise uygulamanın etikete dallanmasına neden olur. İşaretsiz karşılaştırma . operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JG/JNLE -Jump Greater /Jump Not Less or Equal ( Büyükse / Küçük veya Eşit Değilse Dallan ) Kullanım: JG etiket JNLE etiket 158 Değiştirdiği Bayraklar: hiçbiri Eğer Sıfır bayrağı sıfır ise veya işaret bayrağı taşma bayrağına eşitse (ZF=0 veya SF=OF) ,uygulamanın etikete dallanmasına neden olur. İşaretli karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JGE / JNL -Jump Greater or Equal / Jump Not Less (Büyük veya Eşit / Küçük Değilse Dallan) Kullanım : JGE etiket JNL etiket Değiştirdiği Bayraklar:hiçbiri Eğer işaret ve Taşma bayrakları eşitse (SF=OF) ,uygulamanın etikete dallanmasına neden olur. İşaretsiz karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JL/JNGE-Jump less / jump not greater or equal ( Küçükse / Büyük veya Eşit Değilse Dallan ) Kullanım: JL etiket JNGE etiket Değiştirdiği Bayraklar:hiçbiri Eğer İşaret bayrağı Taşma bayrağına eşit değilse (SF ≠ OF) ,uygulamanın etikete dallanmasına neden olur. İşaretsiz karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket : Dallan 16 2-4 Dallanma yok 4 JLE/JNG- Jump Less or Equal / Jump not greater ( Küçük veya Eşit / Büyük Değilse Dallan) Kullanım: JLE etiket JNG etiket Değiştirdiği Bayraklar:hiçbiri Eğer Sıfır bayrağı 1 ise veya işaret bayrağı overflow bayrağına eşit değilse (ZF=1 veya SF ≠ OF) uygulamanın etikete dallanmasına neden olur. İşaretli karşılaştırma . operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JMP -Unconditional Jump (Koşulsuz Dallanma ) Kullanım: JMP hedef Değiştirdiği Bayraklar:Hiçbiri Şartsız olarak kontrolü etikete transfer eder. Dallanma standart olarak -32768 ile 32767 byte arasındaki adres değerlerinde olur.NEAR veya SHORT dallanma IP nin değiştirilmesine neden olurken , FAR dallanma CS ve IP nin değiştrilmesine neden olur. operandlar Büyüklük (Byte) 159 re18 (bağıl) 3 re116 (bağıl) 3 reg16 (near,register dolaylı) 5 hafıza16 (near,hafıza dolaylı) 5 JNC-Jump Not Carry ( Elde Değilse Dallan ) Kullanım: JNC etiket Değiştirdiği Bayraklar:hiçbiri Eğer Elde bayrağı sıfırsa (CF=0) ,uygulamanın etikete dallanmasına neden olur. Fonksiyonel olarak JAE ye ve JNB 'ye benzer. İşaretsiz karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JNE/JNZ -Jump not equal / Jump not zero ( Eşit Değilse / Sıfır Değilse Dallan ) Kullanım: JNE etiket JNZ etiket Değiştirdiği Bayraklar:hiçbiri Eğer zero bayrağı sıfır ise (ZF=0) uygulamanın etikete dallanmasına neden olur.İşaretsiz karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JNO -Jump not overflow (Taşma yoksa Dallan) Kullanım: JNO etiket Değiştirdiği Bayraklar:hiçbiri Eğer Taşma sıfır ise (OV=0), uygulamanın etikete dallanmasına neden olur.İşaretli karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JNS -Jump Not Signed (İşaretli Değilse Dallan ) Kullanım: JNS etiket Değiştirdiği Bayraklar:hiçbiri Eğer İşaret bayrağı sıfır ise ( SF=0), uygulamanın etikete dallanmasına neden olur. İşaretli karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JNP/JPO -Jump Not Parity / Jump Parity odd (Parit Yoksa dallan ) Kullanım: JNP etiket JPO etiket Değiştirdiği Bayraklar: hiçbiri Eğer parity bayrağı sısr ise (PF=0) uygulamanın etikete dallanmasına neden olur. İşaretsiz karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 160 JO -Jump on overflow ( Taşma varsa Dallan ) Kullanım: JO etiket Değiştirdiği Bayraklar: hiçbiri Taşma bayrağı (OF=1) işaretliyse ,uygulamanın etikete dallanmasına neden olur.İşaretli karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JP/ JPE -Jump on Parity / Jump on Parity Even (Parity varsa Dallan ) Kullanım: JP etiket JPE etiket Değiştirdiği Bayraklar: hiçbiri Eğer parity bayrağı işaretliyse , uygulamanın etikete dallanmasına neden olur.İşaretsiz karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 JS -Jump Signed (İşaretli İse Dallan ) Kullanım: JS etiket Değiştirdiği Bayraklar:hiçbiri Eğer işaret bayrağı işaretliyse (SF=1), uygulamanın etikete dallanmasına neden olur.İşaretli karşılaştırma. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 16 2-4 Dallanma yok 4 LAHF -Load Register AH From Flags ( Bayrak Registerlerinin İçerğini AH registerine kopyala) Kullanım: LAHF Değiştirdiği Bayraklar:hiçbiri Bayrak registerlarının 0-7 bitlerini AH'a kopyalar. Buna AF,CF,PF,SF ve ZF bayrakları dahildir, diğer bitler tanımsız. operandlar Saat Darbesi Büyüklük (Byte) yok 4 1 LDS- Load Pointer Using DS ( DS Registeri Kullanark Pointeri Yükle ) Kullanım: LDS hedef,kaynak Kaynak hafızadan 32-bit pointeri, hedef registera ve DS 'ye yükler. Offset hedef regsiter'a ve segment DS 'ye yerleştirilir. Bu komutun kullanılması için; word ün düşük değerlikli hafızadaki adresinin offseti , word’ün yüksek değerlikli hafıza adresinin de segmenti içermesi gerekir. Bu yığından ve kesilim vector tablosundan uzak pointerların yüklenmesini kolaylaştırır. operandlar Büyüklük (Byte) reg16,hafıza32 2-4 LEA -Load Effective Address (Etkin Adresi Yükle ) Kullanım: LEA hedef,kaynak Değiştirdiği Bayraklar:hiçbiri Kaynağın offset adresini , hedefe transfer eder. operandlar Büyüklük (Byte) 161 reg,hafıza 2-4 LES -Load Pointer Using ES (ES Registeri Kullanark Pointeri Yükle ) Kullanım: LES hedef,kaynak Değiştirdiği Bayraklar:Hiçbiri 32-bit pointeri hafıza kaynağından hedef registere ve ES' e yükler. Offset hedef registera , ES segmentine yerleştirilir. Bu komutun kullanılması için düşük değerlikli hafıza adresindeki word'ün offseti, yüksek değerlikli adresteki word'ün segmenti içermesi gerekir. Bu yığından ve kesilim vector tablosundan uzak pointerların yüklenmesini kolaylaştırır. operandlar Büyüklük (Byte) reg,hafıza 2-4 LOCK -Lock Bus (Bus’ ı Kilitle ) Kullanım: LOCK Değiştirdiği Bayraklar:hiçbiri Bu komut CPU'nun , sonraki komut işletilirken bus lock sinyali ileri sürmesine neden olan bir önektir. İki işlemcinin aynı data konumunu güncelleştirmesini engellemek için kullanılır.Bu sadece bus öncesi XCHG, MOV, IN ve OUT komutlarını kilitlemek için kullanılmalıdır. operandlar Saat Darbesi Büyüklük (Byte) yok 2 1 LODS -Load String (Byte , word or double) (Karakter Katarını Yükle ) Kullanım: LODS kaynak LODSB LODSW Değiştirdiği Bayraklar:hiçbiri DS:SI tarafından adreslenen string elementi akümülatöre transfer eder. SI operandın büyüklüğüne ve kullanılan komuta dayandırılarak arttırılır. Eğer yönlendirme bayrağı işaretliyse (DF=1) ise SI azaltılır, eğer yönlendirme bayrağı sıfır ise (DF=0) SI arttırılır. REP öneki ile kullanılır. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 18 2 Dallanma yok 5 LOOP -Decrement CX and Loop if CX Not Zero ( CX Registerini Azalt ve CX=0 Değilse Dön ) Kullanım: LOOP etiket Değiştirdiği Bayraklar: hiçbiri CX'i 1 azaltır ve eğer CX sıfır değilse etikete dallanır. Etiket operandı , Loop komutunu takip eden komutun -128 veya 127 byte'ı içinde olmalıdır. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 18 2 Dallanma yok 5 LOOPE / LOOPZ -Loop While Equal / Loop while zero ( Eşit ise / Sıfır ise Dön ) Kullanım: LOOPE etiket LOOPZ etiket Değiştirdiği Bayraklar: hiçbiri 162 CX registeri 1 azaltır (bayrakları değiştirmeden) ve eğer CX ≠ 0 ise ve sıfır bayrağı işaretliyse (ZF=1) etiketi dallanır. Etiket operandı , loop komutunu takip eden komutun -128 ya da 127 byte 'ı içinde olmalıdır. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallanma 18 2 Dallanma yok 5 LOOPNZ/LOOPNE -Loop While Not Zero / Loop While Not Equal (Sıfır Değilse / Eşit Değilse Dön) Kullanım: LOOPNZ etiket LOOPNE etiket Değiştirdiği Bayraklar:hiçbiri CX'i 1 azaltır (bayrakları değiştirmeden) ve eğer CX ≠ 0 ise ve sıfır bayrağı sıfır ise (ZF=0) etikete dallanır. Etiket operandı , loop komutunu takip eden komutun -128 ya da 127 byte 'ı içinde olmalıdır. operandlar Saat Darbesi Büyüklük (Byte) etiket: Dallan 19 2 Dallanma yok 5 MOV -Move Byte or Word (Byte veya Word Kopyala ) Kullanım: MOV hedef,kaynak Değiştirdiği Bayraklar: hiçbiri Kaynak operanddan ,hedef operanda byte veya word kopyalar . operandlar Büyüklük (Byte) reg,reg 2 hafıza,reg 2-4 reg,hafıza 2-4 hafıza,öncel 3-6 reg,öncel 2-3 hafıza,accum 3 accum,hafıza 3 segreg,reg16 2 segreg,hafıza16 2-4 reg16,segreg 2 hafıza16,segreg 2-4 MOVS -Move String (Byte or Word) ( Byte veya Word Karakter Katarını Kopyala ) Kullanım: MOVS hedef,kaynak MOVSB MOVSW Değiştirdiği Bayraklar:hiçbiri DS:SI tarafından adreslenen datayı (operandlar verilmiş olsa bile) ES:DI hedef konumuna kopyalar. 163 SI ve DI 'yı, kullanılan operandın veya komutun boyutuna göre ,günceller. SI ve DI yön bayrağı sıfırlandığında (DF=0) arttırılır ve yön registeri işaretli olduğunda (DF=1) da azaltılır. REP önekleri ile kullanılır. operandlar Saat Darbesi Büyüklük (Byte) hedef,kaynak 18 1 MUL -Unsigned Multiply (İşaretsiz Çarpma ) Kullanım: MUL kaynak Değiştirdiği Bayraklar: CF OF (AF,PF,SF,ZF tanımsız) Kaynağın akümülatör ile işaretsiz çarpımı. Eğer kaynak bir byte değer ise, AL diğer çarpılan olarak kullanılır ve sonuç AX'e yerleştirilir. Eğer kaynak bir word değerse, AX kaynakla çapılır ve sonuç DX:AX 'e gönderilir. operandlar Büyüklük (Byte) reg8 2 reg16 2 hafıza8 2-4 hafıza16 2-4 NEG -Two's complement negation ( 2’ ye Göre Tümleyenini Al ) Kullanım: NEG hedef Değiştirdiği Bayraklar:AF CF OF PF SF ZF Hedefi sıfırdan çıkartır ve hedefin 2ye tümleyninin tekrar hedefe yükler. Büyüklük (Byte) operandlar reg 2 hafıza 2-4 NOP -No operation ( İşlem Yok ) Kullanım: NOP Bu hiçbirşey yapma komutudur.Zaman ve yer kazandırır ve en çok code segmentlerini birleştirmede kullanışlıdır. operandlar Saat Darbesi Büyüklük (Byte) yok 3 1 NOT -One's Compliment Negation (Logical NOT) (1‘e Göre Tümleyenini Al ) Kullanım: NOT hedef Değiştirdiği Bayraklar:hiçbiri Yeni bir 1’ göre tümleyenini oluşturarak hedef operandın bitlerinin tersini alır. operandlar Büyüklük (Byte) reg 2 hafıza 2-4 OR -Inclusive Logical OR ( Veya ) Kullanım: OR hedef,kaynak Değiştirdiği Bayraklar: CF OF PF SF ZF (AF tanımsız) İki operandın mantıksal veya işlemini yapar.Sonucu hedef oprenda yükler. Operandlar Büyüklük (Byte) reg,reg 2 hafıza,reg 2-4 reg,hafıza 2-4 reg,öncel 3-4 hafıza8,öncel8 3-6 164 hafıza16,öncel16 accum,öncel 3-6 2-3 OUT -Output Data to Port ( Porta Yaz ) Kullanım: OUT port,accum Değiştirdiği Bayraklar:hiçbiri Belirli bir port adresine , AL deki byte'ı ,veya AX deki wordü eder.Eğer port numarası 0-255 arası ise öncel olarak belirtilebilir.255 den büyük port numaraları DX de belirtilmesi gerekir. operandlar Saat Darbesi Büyüklük (Byte) öncel8,accum 10/14 2 DX,accum 8/12 1 POP -Pop Word off stack ( Yığında Word Çek ) Kullanım: POP hedef Değiştirdiği Bayraklar: hiçbiri O anki yığının en üstündeki word’ ü (SS:SP) hedefe transfer eder ve sonra SP' yi yeni yığın üst noktasına doğru iki arttırır. CS registeri hedef olarak kullanılmaz. operandlar Büyüklük (Byte) reg16 2 segreg 1 hafıza16 2-4 POPF -Pop Flags off Stack (Yığında Bayrak Registerine Çek ) Kullanım: POPF Değiştirdiği Bayraklar: bütün bayraklar Yığındaki word değeri bayrak registerlarına çeker ve sonra SP yi 2 arttırır. Saat Darbesi Büyüklük (Byte) operandlar none 8/12 1 PUSH -Push Word onto Stack ( Yığına İt ) Kullanım: PUSH kaynak Değiştirdiği bayraklar:hiçbiri SP yi operandın büyüklüğü kadar azaltır ve kaynaktan yığın üst noktasına (SS:SP) bir word transfer eder. operandlar Büyüklük (Byte) reg16 1 hafıza16 2-4 segreg 1 PUSHF -Push Flags onto Stack ( Bayrak Registerinin İçeriğini Yığına İt ) Kullanım: PUSHF Değiştirdiği Bayraklar: hiçbiri Bayrak registerlerini yığına'a transfer eder. operandlar Saat Darbesi Büyüklük (Byte) yok 10/14 1 165 RCL -Rotate Through Carry Left ( Elde Bayrağı İle Sola Doğru Döndür ) Kullanımı : RCL hedef ,sayım değeri Değiştirdiği Bayraklar: CF OF Hedefin bitlerini sola doğru (sayım değeri) kere döndürür. Ve bütün data sağdan tekrar girilerek sol tarafa itilir. Elde bayrağı döndürülen son biti tutar. operandlar Büyüklük (Byte) reg,1 2 hafıza,1 2-4 reg,CL 2 hafıza,CL 2-4 RCR -Rotate Through Carry Right ( Elde Bayrağı İle Sağa Doğru Döndür ) Kullanım: RCR hedef,sayım değeri Değiştirdiği Bayraklar: CF OF Hedefin bitlerini sağa doğru (sayım değeri) kere döndürür. Ve bütün data soldan tekrar girilerek sağ tarafa itilir. Elde bayrağı döndürülen son biti tutar. operandlar Büyüklük (Byte) reg,1 2 hafıza,1 2-4 reg,CL 2 hafıza,CL 2-4 REP -Repeat String Operation ( Karakter Katarı Tekrarla Öneki ) Kullanım: REP Değiştirdiği Bayraklar: hiçbiri Karakter Katarı komutlarının uygulamasını CX ≠ 0 olduğu sürece tekrarlar. Her karakter katarı işleminden sonra , CX azaltılır ve Sıfır bayrağı test edilir. operandlar Saat Darbesi Büyüklük (Byte) yok 2 1 REPE/REPZ -Repeat Equal /Repeat Zero ( Eşit İse / Sıfır İse Tekrarla ) Kullanım: REPE REPZ Değiştirdiği Bayraklar:hiçbiri Karakter Katarı komutlarının uygulanmasını CX ≠ 0 ve Sıfır bayrağı bir ( ZF=1) olduğu sürece tekrar eder CX azaltılır ve Sıfır bayrağı her karakter katarı işleminden sonra test edilir. operandlar Saat Darbesi Büyüklük (Byte) yok 2 1 REPNE/REPNZ -Repeat not Equal/Repeat Not Zero ( Esit Değil ise / Sıfır değil İse Tekrarla ) Kullanım: REPNE REPNZ Değiştirdiği Bayraklar: hiçbiri Karakter Katarı komutlarının uygulanmasını CX ≠0 ve Sıfır bayrağı sıfır olduğu ( ZF=0) sürece tekrar eder CX azaltılır ve Sıfır bayrağı her karakter katarı işleminden sonra test edilir. operandlar Saat Darbesi Büyüklük (Byte) yok 2 1 RET/RETF -Return From Procedure ( Alt Proğramdan Geri Dön ) Kullanım: RET nBytes 166 RETF nBytes RETN nBytes Değiştirdiği Bayraklar:hiçbiri Alt programın konrtolünü yığın tarafından tutulan uygulama adresine geri yollar. "n byte" isteğe bağlı bir numaradır. operandlar Saat Darbesi Büyüklük (Byte) retn 16/20 1 retn öncel 20/24 3 retf 26/34 1 retf öncel 25/33 3 ROL -Rotate Left ( Sola Döndür ) Kullanım: ROL hedef,sayım değeri Değiştirdiği Bayraklar: CF OF Hedefin bitlerini sola doğru (sayım değeri) kere döndürür. Ve bütün data sağdan tekrar girilerek sol tarafa itilir. Elde bayrağı son döndürülen bitin değerini içerir. operandlar Büyüklük (Byte) reg,1 2 hafıza,1 2-4 reg,CL 2 hafıza,CL 2-4 ROR -Rotate Right ( Sağa Döndür ) Kullanım: ROR hedef , sayım değeri Değiştirdiği Bayraklar: CF OF Hedefin bitlerini sağa doğru (sayım değeri) kere döndürür. Ve bütün data soldan tekrar girilerek sağ tarafa itilir. Elde bayrağı son döndürülen bitin değerini içerir. Büyüklük (Byte) operandlar reg,1 2 hafıza,1 2-4 reg,CL 2 hafıza,CL 2-4 SAHF -Store AH Register into Flags ( AH Registerinin İçeriğini Bayrak Registerine Yükle ) Kullanım: SAHF Değiştirdiği Bayraklar: AF CF PF SF ZF AH nın 0-7 bitlerini bayrak registerina transfer eder. Bu AF,CF,PF,SF ve ZF yi içerir. operandlar Saat Darbesi Büyüklük (Byte) yok 4 1 167 SAL/SHL -Shift Arithmetic Left/Shift Logical Left ( Aritmetik / Mantıksal Sola Kaydır ) Kullanım: SAL hedef,sayım değeri SHL hedef, sayım Değiştirdiği Bayraklar:CF OF PF SF ZF (AF tanımsız) Hedefi (sayım değeri) kadar bit sola kaydırır, sağdan sıfır girer. Elde bayrağı en son değiştirilen biti içerir. operandlar Büyüklük (Byte) reg,1 2 hafıza,1 2-4 reg,CL 2 hafıza,CL 2-4 SAR -Shift Arithmetic Right ( Aritmetik Sağa Kaydır ) Kullanım: SAR hedef,sayım değeri Değiştirdiği Bayraklar: CF OF PF SF ZF (AF tanımsız) Hedefi sağa (sayım değeri) bit kadar kaydırır, o anki işaret biti ensol bite kopyalanır.Elde bayrağı en son değiştirilen biti içerir. operandlar Büyüklük (Byte) reg,1 2 hafıza,1 2-4 reg,CL 2 hafıza,CL 2-4 SBB -Substract with Borrow ( Ödünç Alarak Çıkart ) Kullanım: SBB hedef,kaynak Değiştirdiği Bayraklar: AF CF OF PF SF ZF Hedeften kaynağı çıkartır, eğer Elde bayrağı işaretliyse ( CF=1) ilave olarak 1 çıkartır.Sonuçlar hedefde saklanır. Büyüklük (Byte) operandlar reg,reg 2 hafıza,reg 2-4 reg,hafıza 2-4 reg,öncel 3-4 hafıza,öncel 3-6 accum,öncel 2-3 SCAS -Scan String (byte,word or doubleword) ( Karakter Katarı Ara ) Kullanım: SCAS karakter katarı SCASB SCASW Değiştirdiği Bayraklar: AF CF OF PF SF ZF Akümülatörden ES:DI daki değeri karşılaştırır.ve çıkartmadakine benzer şekilde bayrakları işaretler. komut formatına ve yönlendirme bayrağının konumuna göre DI arttırılır/azaltılır .REP önekleriyle kullanılır. operandlar Saat Darbesi Büyüklük (Byte) karakter katarı 15 1 168 SHR -Shift Logical right ( Mantıksal Sağa Kaydır ) Kullanım: SHR hedef,sayım değeri Değiştirdiği Bayraklar: CF OF PF SF ZF (AF tanımsız) Hedefi (sayım değeri) bit kadar sağa kaydırır ve sıfırlar soldan girer. Elde bayrağı son değiştirilen biti içerir. Büyüklük (Byte) operandlar reg,1 2 hafıza,1 2-4 reg,CL 2 hafıza,CL 2-4 STC -Set Carry ( Elde Bayrağını Bir’le ) Kullanım: STC Değiştirdiği Bayraklar: CF Elde bayrağını 1 yapar. operandlar Saat Darbesi Büyüklük (Byte) yok 2 1 STD -Set Direction Flag ( Yön Bayrağını Bir’le ) Kullanım: STD Değiştirdiği Bayraklar:DF Yönlendirme bayrağını 1 yaparak ,Karakter katarı komutlarının SI ve DI nın otomatik olarak arttırılması yerine otomatik azaltılmasına neden olur. operandlar Saat Darbesi Büyüklük (Byte) yok 2 1 STI -Set Interrupt Flag (enable interrupts) ( Kesilim Bayrağını Bir’le – kesilimi etkin yap ) Kullanım: STI Değiştirdiği Bayraklar: IF Kesilim bayrağını 1 yapar ve CPU donanım interruptlarının tümünün tanınmasını sağlar. Saat Darbesi Büyüklük (Byte) operandlar yok 2 1 STOS -Store String(Byte,word or doubleword) ( Karakter Katarıını Sakla ) Kullanım: STOS hedef STOSB STOSW STOSD Değiştirdiği Bayraklar: hiçbiri Akümülatördeki değeri ES:DI konumunda saklar (operand verilse bile). DI operandın büyüklüğüne (veya komut formatına) ve yönlendirme bayrağının durumuna göre arttırılır/azaltılır. REP önekiyle kullanılır. operandlar Saat Darbesi Büyüklük (Byte) hedef 11 1 SUB -Substract ( Çıkart ) Kullanım: SUB hedef, kaynak Değiştirdiği Bayraklar: AF CF OF PF SF ZF Kaynak hedeften çıkartılır ve sonuç hedefte tutulur. 169 operandlar reg,reg hafıza,reg reg,hafıza reg,öncel hafıza,öncel accum,öncel Büyüklük (Byte) 2 2-4 2-4 3-4 3-6 2-3 TEST -Test for Bit Pattern ( Bit Pattreni Test Et ) Kullanım: TEST hedef,kaynak Değiştirdiği Bayraklar: CF OF PF SF ZF (AF tanımsız) İki operanda mantıksal ve uygular ve bayrak registerını günceller, sonuçları saklamaz. operandlar Büyüklük (Byte) reg,reg 2 reg,hafıza 2-4 hafıza,reg 2-4 reg,öncel 3-4 hafıza,öncel 3-6 accum,öncel 2-3 WAIT -Event wait ( Bekle ) Kullanım: WAIT Değiştirdiği Bayraklar: hiçbiri Matematik işlemcinin işlemin bittiğini işaret edene kadar CPU bekleme konumuna geçer .Bu komut geçici olarak Matematik işlemci tarafından kullanılan hafızaya CPU nun erişimini önler. operandlar Saat Darbesi Büyüklük (Byte) yok 4 1 XCHG -Exchange ( Değiş tokuş Et ) Kullanım: XCHG hedef,kaynak Değiştirdiği Bayraklar: hiçbiri Kaynak ve hedefin içeriklerini birbiriyle değiştirir. operandlar Büyüklük (Byte) reg,reg 2 hafıza,reg 2-4 reg,hafıza 2-4 accum,reg 1 reg,accum 1 XLAT/XLATB –Translate ( Çevir ) Kullanım: XLAT çeviri tablosu Değiştirdiği Bayraklar: hiçbiri AL içerisindeki byte'ı BX tarafından adreslenen bir kullanıcı tablosundaki byte ile değiştirir.AL nin orjinal değeri çeviri tablosuna indextir. operandlar Saat Darbesi Büyüklük (Byte) tablo 11 1 170 XOR -Exclusive OR ( EXOR Özel Veya ) Kullanım: XOR hedef,kaynak Değiştirdiği Bayraklar: CF OF PF SF ZF (AF tanımsız) Operandlar arasında Exor işlemi yapar ve sonucu hedefte saklar. operandlar reg,reg hafıza,reg reg,hafıza reg,öncel hafıza,öncel accum,öncel Büyüklük (Byte) 2 2-4 2-4 3-4 3-6 2-3 171 INTERRUPTLAR: BIOS Interrupt INT 13H Fonksiyon 00h – (Disket/Hard Disk) Başlangıç Durumuna Getirir: Bu fonksiyon floppy denetçisini ve sürücüsünü başlangıç durumuna getirir ve sonunda o anki fonsiyonu durdurur. Bu fonksiyonun tamamlanmasından sonra denetçi ve sürücü iyi tanımlanmış durumda olur. Register: Çağrı Değeri: Dönen Değer: AH 00h hata kodu 1) 2) DL sürücü Elde 1) bkz F-2 2) Floppy disk sürücüsü : 00h hata varsa Fonksiyon 01h: En son Disket ya da Hard Disk İşleminin durumunu okur. (Hata Kodu) Bu fonksiyon en son sabit disk ya da disket sürücüsü işleminin sonlandırma durumunu belirtir. Bu durum kodu genellikle işlemin sonlandırılmasından sonra ah ile aynı formatta Register’ın içine geri döner. Bu fonksiyon bir işlemin tamamlanmasından sonraki durumu belirtmek istemiyorsanız yararlıdır. Ve durum byte’ıyla birlikte ah’ın içeriği zaten başka bir talimatla yok edilmiştir. Register: AH DL Çağrı Değeri: 01h sürücü 2) Dönen Değer: hata kodu1) Elde 1) bkz F-2 2) Disket sürücü : 00h hata varsa Fonksiyon 02h – Sektörleri Okur (Disket / Hard Disk) Disket / Hard Disk’in okuma tamponunun içinden bir ya da daha fazla sektör okunur. Tampon okuma sektörleri barındıracak kadar uzun olmalıdır. Bu durum olmazsa, 02h fonksiyonu veriyi ana belleğin üzerine yazar; ve sonuçta sistem çöker. Register: AH AL CH CL DH DL ES BX Elde 2) bkz F-2 Çağrı Değeri: Dönen Değer: 02h hata kodu 1) okunacak sektörün numarası iz/silindir sektör kafa sürücü okuma tamponunun segmenti okuma tamponunun ofseti hata varsa Fonksiyon 03h – Sektörleri Yazar (Disket / Hard Disk) 172 Bu fonksiyon ana belleğin yazma tamponundan disket ya da Hard Disk’in üzerinde bir ya da daha fazla sektör yazar. Bu tampon yazılabilecek bütün verileri içerir. Bu veri transferi yalnızca 512 byte ile olur. Eğer tamponunuz kısmen yazma verisiyle dolmuşsa 03h fonksiyonun değerini aktarır. Bütün sektörler tüm register’ların programlanana kadar girintisiz veri de disk üzerindedir. Register: AH AL CH CL DH DL ES BX Elde 2) bkz F-2 Çağrı Değeri: Dönen Değer: 03h hata kodu 1) okunacak sektörün numarası iz/silindir sektör kafa sürücü okuma tamponunun segmenti okuma tamponunun ofseti hata varsa Fonksiyon 04h – Sektörleri Doğrular (Disket/ HD) Bu fonksiyon ana belleğin içindeki doğrulama tamponunun içeriği ile disket ya da hard disk üzerindeki bir ya da dah fazla sektörün içeriğini karşılaştırır. Ya da bir ya da daha çok sektör bulunup okunabildiğinde ve ve geçerli CRC kodu geri gönderildiğinde son durumda hiçbir data karşılaştırılmamıştır. Register: AH AL CH CL DH DL ES BX Elde 2) bkz F-2 Çağrı Değeri: Dönen Değer: 04h hata kodu 1) okunacak sektörün numarası iz/silindir sektör kafa sürücü okuma tamponunun segmenti okuma tamponunun ofseti hata varsa Fonksiyon 05h – İz ve Silindiri Formatlar (Disket / HD) Bu fonksiyon sektörlerin bir iz ya da silindirini formatlar. Bir AT üzerinde ilk olarak 17h ya da 18h orta tipi onarabilirsiniz. Formatlama işlemi için her sektör formatlamak için bir format tamponunun format bilgisini içermesi gereklidir. Eğer birkaç sektör formatlamak isterseniz format tamponun bütün sektörler için format bilgisini saklamak için yeteri kadar büyük olması gerekir. Denetçi bilgiyi format tamponunun içine yazar. (Kararlı sektörün ID alanı içine) ve data’yı okurken ve yazarken doğru sektörü tanımlamak için kullanılır. Register: AH AL CH CL Çağrı Değeri: Dönen Değer: 05h hata kodu 1) okunacak sektörün numarası iz/silindir sektör 173 DH DL ES BX Elde 1) bkz F-2 2) bkz F-4 kafa sürücü okuma tamponunun segmenti okuma tamponunun ofseti hata varsa Fonksiyon 06h – Formatlar ve Track’i İşaretler (HD) Bu fonksiyon daha fazla data kaydında kullanılmayacak ve hatalı sektörsüz bir iz işaretler. Bu fonksiyon yalnızca XT hard disk denetçisi için geçerlidir. Register: AH AL CH CL DH DL Elde 2) bkz F-2 Çağrı Değeri: 06h boş sayfa ekle Dönen Değer: hata kodu 1) silindir sektör kafa sürücü hata varsa Fonksiyon 07h – Sürücüyü Formatlar (HD) Bu fonksiyon sürücüyü tanımlanmış silindirden itibaren formatlar. Bu fonksiyon yalnızca XT hard disk denetçisi için geçerlidir. Register: AH AL CH CL DH DL Elde 2) bkz F-2 Çağrı Değeri: 07h boş sayfa ekle Dönen Değer: hata kodu 1) silindir sektör kafa sürücü hata varsa Fonksiyon 08h – Sürücü Parametrelerini Tanımlar (Disket) Bu fonksiyon floppuy disk’in geometrik parametrelerini tanımlar. Data BIOS tablosundan açılır ve kurulu ürücüden geometrisi yansıtılır. Fakat bu data ortamına girmiş değildir. Register: AH BH BL CH CL DH DL Çağrı Değeri: 08h sürücü Dönen Değer: hata kodu 1) 0 sürücü tipi 2) silindirini numarası -1 her izin sektörü kafaların numarası sürücülerin numarası 174 ES tablo segmenti parametresi DI tablo ofseti parametresi Elde hata varsa 1) bkz F-2 2) 0=hard disk, 1=360 kbyte, 2=1,2 Mbyte, 3=720 kbyte Fonksiyon 08h – Sürücü Parametrelerini Tanımlar (HD) Register: AH BH Çağrı Değeri: 08h Dönen Değer: hata kodu 1) 0 BL sürücü tipi 2) CH silindirini numarası -1 CL her izin sektörü DH kafaların numarası DL sürücü sürücülerin numarası ES tablo segmenti parametresi DI tablo ofseti parametresi Elde hata varsa 3) bkz F-2 4) 0=hard disk, 1=360 kbyte, 2=1,2 Mbyte, 3=720 kbyte Fonksiuyon 09h – Sürücü Parametrelerini Beirtir (HD) Bu fonksiyon hard disk geometrik parametrelerini belirtir ve uydurur. Kararlı parametreler bir tablo içinde saklanır. (bkz. F-3) Bunlar yalancı kesme vektörleri olan 41h ve 46h tarafından uzak adres olarak tutulur. Bu fonksiyon çağrıldıktan sonra, BIOS kararlı tablodaki değerleri kullanır. Fonksiyon 01h – Mouse İmlecini Gösterir / İmleç Bayrağının Artımı: Register: AH DL Elde 2) bkz F-2 Çağrı Değeri: 09h sürücü Dönen Değer: hata kodu 1) sürücünün numarası hata varsa Fonksiyon 0Dh – Hard Disk Reseti (HD) Bu fonksiyon adreslenmiş sürücüyü resetler. Register: AH DL Elde 2) bkz F-2 Çağrı Değeri: 09h sürücü Dönen Değer: hata kodu 1) hata varsa F-2 Hata Kodları: 175 Hata Kodu Anlamı Floppy için (AH değeri) 00h 01h 02h 03h 04h 05h 07h 08h 09h 10h 11h 20h 40h 80h BBh FFh HD için geçerliliği geçerliliği hata yok geçersiz fonksiyon numarası adres işareti bulunamadı disk yazmaya karşı korumalı sektör bulunamadı başarısız reset hatalı başlatma DMA taşması DMA segment taşması okuma hatası data okuma hatası ECC doğrulaması başarılı denetçi hatası iz bulunamadı sürücü yasnıtı BIOS hatası Tanımlanamayan hata evet evet evet evet evet evet evet hayır evet evet evet evet hayır evet hayır evet evet evet hayır evet evet evet evet evet evet hayır hayır F-3 Hard disk Sürücüsü Parametre Tablosu: 176 evet evet evet evet evet F-4 Format Tamponu: İçerik Ofset Boyut 00h byte sektörün izi formatsız 01h byte sektörün kafası formatsız 02h byte sektörün numarası 03h byte her sektör byte’ının numarası *) *) 0=128, 1=256, 2=512, 3=1024 Arabirimlere Erişim: I-1 Paralel Arayüz: Paralel arabirime erişmek için DOS’un 21h kesmesinin dört fonksiyonu BIOS’un 17h kesmesinin üç fonksiyonu kullanılır. I-1-1 DOS Fonksiyonları: Bu fonksiyonlar DOS’un 21h kesmesini çağırarak erişirler. Fonksiyon 05h – Yazma: Fonksiyon paralel arayüz PRN’ye bir karakter aktarır. Register Çağrı Değeri AH 05h DL yazılan karakterin Dönen Değer ASCII kodu Elde Fonksiyon 40h – Dosya / Unit Yazar: Bu fonksiyon bir tampondan paralel arayüze bir ya da daha çok karakter aktarır. Genellikle PRN tutucu 4’e atanmıştır. Aksi halde tutcuyu 3. fonksiyonla geri döndürmelisiniz. “dosya / aygıt açma” Register Çağrı Değeri AH 40h AX BX CX DX DS Dönen Değer hata kodu / byte numarası *) tutucu yazılan byte’ların numarası yazma tamponu ofseti yazma tamponu segmenti 177 Elde hata varsa *) sistem hata kodu, eğer elde ayarlanmışsa ya da güncel yazılmış byte’ların numarası ayarlanmışsa I-1-2 BIOS Fonksiyonları: Bu fonksiyonlar BIOS interrupt 17h’ı çağırarak erişirler. Fonksiyon 00h – Paralel Arayüz ve Yazıcıya Karakter Çıktı Verir: Bu fonksiyon paralel arabirime bir karakter çıktı verir. Register Çağrı Değeri AH 00h AL karakterin ASCII kodu DX arayüz / yazıcı numarası 2) Dönen Değer durum 1) Elde 1) bkz. I-1-3 2) 0=LPT1=PRN, 1=LPT2, 2=LPT3, 3=LPT4 Fonksiyon 01h – Paralel Arabirimi ve Yazıcıyı Başlangıç Durumuna Getirir: Bu fonksiyon paralel arabirimi ve bağlı yazıcıyı başlagıç durumuna getirir. Register Çağrı Değeri AH 00h DX Dönen Değer durum 1) arabirim / yazıcı numarası 2) Elde 1) bkz. I-1-3 2) 0=LPT1=PRN, 1=LPT2, 2=LPT3, 3=LPT4 Fonksyon 02h – Yazıcı Durumunu Belirtir: Bu fonksiyon bağlı yazıcının ve arabirimin durumunu belirtir. Register Çağrı Değeri AH 00h DX Dönen Değer durum arabirim / yazıcı numarası 2) Elde 178 1) 1) bkz. I-1-3 2) 0=LPT1=PRN, 1=LPT2, 2=LPT3, 3=LPT4 I-1-3 Yazıcı Durum Byte’ı: I-2 Seri Arabirim: Seri arabirim için DOS 21h kesmesinin 4 fonksiyonu BIOS 14h kesmesinin 7 fonksiyonu uygundur. I-2-1 DOS Fonksiyonları: Bu fonksiyonlar DOS’un 21h kesmesini çağırarak erişirler. Fonksiyon 03h – Seri Arayüzden Karakter Okur: Bu fonksiyon AUX’a uydurarak COM1 seri arabirimden bir karakter okur. Register Çağrı Değeri AH 03h AL Dönen Değer kabul edilmiş karakter Fonksiyon 04h – Seri Arabirim Yoluyla Karakter Çıktı Verir: Bu fonksiyon COM1 seri arabirim yoluyla AUX’a uydururak bir karakter çıktı verir. Register Çağrı Değeri AH 04h Dönen Değer 179 DL karakter çıktısının ASCII kodu Elde Fonksiyon 03fh – Dosya / Aygıt Okur: Bu fonksiyon bir tampon içerisinden bir seri arabirimden bir ya da daha çok karakter okur. Genellikle AUX COM1’i atanmış tutucu 3’e uydurur. Aksi halde tutucuyu 3dh fonksiyonuyla geri döndürmelisiniz. Dosya / Sürücü açmak arayüzü ilgilendirir. Register Çağrı Değeri AH 03fh AX Dönen Değer hata kodu / byte numarası *) BX tutucu CX okunan byte’ların numarası DX okuma tamponu ofseti DS okuma tamponu segmenti Elde hata varsa *) Elde ayarlanmışsa sistem hata kodu; ya da byte’ların numarası hale okunuyor. Fonksiyon 40h – Dosya / Sürücü Yazar: Bu fonksiyon seri arabirim yoluyla bir tampondan bir ya da daha çok karakter çıktı verir. Genellikle AUX COM1’i atanmış tutucu 3’e uydurur. Aksi halde tutucuyu 3dh fonksiyonuyla geri döndürmelisiniz. Dosya / Sürücü açmak arabirimi ilgilendirir. Register Çağrı Değeri AH 03fh AX Dönen Değer hata kodu / byte numarası *) BX tutucu CX okunan byte’ların numarası DX okuma tamponu ofseti DS okuma tamponu segmenti Elde hata varsa *) Elde ayarlanmışsa sistem hata kodu; ya da byte’ların numarası hale okunuyor. I-2-2 BIOS Fonksiyonları: Bu fonksiyonlar BIOS’un 14h kesmesi çağrısı yoluyla erişirler. 180 Fonksiyon 00h – Seri Arabirimi Başlangıç Durumuna Getirir: Bu fonksiyon seri arabirimi başlangıç durumuna getirir. Register Çağrı Değeri AH 00h AL parametre byte’ı 2) gönderme durumu 1) modem durumu 3) arabirim numarası 4) DX 1) 2) 3) 4) Dönen Değer bkz. I-2-3 bkz. I-2-5 bkz I-2-4 0=COM1=AUX, 1=COM2, 2=COM3, 3=COM4 Fonksiyon 01h – Seri Arayüz Yoluyla Karakter Çıktısı Verir: Bu fonksiyon seri arabirim yoluyla karakter çıktısı verir. Register Çağrı Değeri AH 01h AL DX Dönen Değer gönderme durumu 1) karakter arabirim numarası 2) 1) bkz. I-2-3 2) 0=COM1=AUX, 1=COM2, 2=COM3, 3=COM4 Fonksiyon 02h – Seri Arabirim Yoluyla Karakter Çıktısı Okur: Bu fonksiyon seri arabirim yoluyla karakter çıktısı okur. Register Çağrı Değeri AH 01h AL DX Dönen Değer gönderme durumu 1) karakter arabirim numarası 2) 3) bkz. I-2-3 4) 0=COM1=AUX, 1=COM2, 2=COM3, 3=COM4 Fonksiyon 03h – Seri Arabirim’in Durumunu Belirtir: Bu fonksiyon seri arabirim’in o anki durumunu belirtir. Register Çağrı Değeri AH 03h Dönen Değer gönderme durumu 1) 181 AL DX modem durumu arabirim numarası 2) 1) bkz. I-2-3 2) bkz. I-2-4 3) 0=COM1=AUX, 1=COM2, 2=COM3, 3=COM4 Fonksiyon 04h – Seri Arabirim Uzatımını Başlatır. Bu fonksiyon seri arabirimin bir uzatılmış başlatmasını dışa taşır. Bu fonksiyon yalnız PS/2’lerde geçerlidir. Register Çağrı Değeri AH 04h AL gönderme durumu 1) modem durumu 2) kesme ayarı BH parite BL CH Dönen Değer stop bitleri data bitleri CL boud rate DX arabirim numarası 3) 1) bkz. I-2-3 2) bkz. I-2-4 3) 0=COM1=AUX, 1=COM2, 2=COM3, 3=COM4 <<<K-5>>> Fonksiyon 05h – Alt Fonksiyon 00h – Modem Kontrol Register’ını Okur : Bu fonksiyon seri arabirimin modem kontrol register’ını okur. Bu fonksiyon yalnız PS/2’de geçerlidir. Register Çağrı Değeri AH 05h AL Dönen Değer 00h BL DX modem kontrol register’ı arayüz numarası 3) 1) bkz. I-2-6 2) 0=COM1=AUX, 1=COM2, 2=COM3, 3=COM4 182 Fonksiyon 05h – Alt Fonksiyon 00h – Modem Kontrol Register’ını Yazar : Bu fonksiyon seri arayüzün modem kontrol register’ını yazar. Bu fonksiyon yalnız PS/2’de geçerli. Register Çağrı Değeri AH 05h AL Dönen Değer 00h BL DX modem kontrol register’ı arabirim numarası 3) 3) bkz. I-2-6 4) 0=COM1=AUX, 1=COM2, 2=COM3, 3=COM4 I-2-3 Gönderme Durumu: <<<K-6>>> I-2-4 Modem Durumu: <<<K-7>>> I-2-3 Parametre Byte’ı 183 I-2-3Modem Kontrol Register’ı J Klavye ve Fare Erişimi: J-1: Kalvye: - 7 DOS fonksiyonu DOS’un 21h kesmesi çağrısıyla erişirler. Klavye BIOS’un 15h kesmesinin anlamıyla doğrudan erişebilir. Bazı BIOS versiyonlarıyla, donanım kesme tutucusu 09h INT 15h’ın 4fh fonksiyonunu çağırır ve tutucunun tarama koduna geçer. SysReg tuşuna basıldığında ya da bırakıldığında tutucunun 09h kümesi INT 15h’ın 85h fonksiyonunu çağırır. J-1-1 DOS Fonksiyonları: Fonksiyon 01h – Echo’yla Karakter Girişi: Bu fonksiyon klavye tamponundan bir karakter byte okur. Ve aynı zamanda karakter yoluyla standart çıktı aygıtına çıktı verir. Fonksiyon tuşları gibi non-ASCII (ASCII olmayan)’lar için fonksiyonu ikinci kez çağırmalısınız. Birincide 00h kodu döner, ikincide tuşun tarama kodu çağrılır. Register Çağrı Değeri AH 01h Dönen Değer AL ASCII kod Fonksiyon 06h – Standart Girdi Aygıtından Denetimsiz Olarak Karakter Girer: 184 Bu fonksiyon klavye tamponundan bir karakter okumaya teşebbüs eder. Ve bir uygun karakteri beklemez. F1 gibi non-ASCII tuşlar ile ilk çağrıda 0’a eşit kod geri döner ve ikincide basılan tuşun tarama kodu çağrılır. Bu fonksiyon klavyeden standart girdi aygıtı kadar uzun bir şekilde okur. Ctrl-C gibi kontrol karakterleri açıklanmamıştır. Register Çağrı Değeri AH 06h Dönen Değer AL DL ASCII kod ffh Zero 1= cr karakter okuma 0= hiçbir karakter uygun değil Fonksiyon 07h- Klavyeden Doğrudan Karakter Girdisi Alır: Bu fonksiyon klavye tamponundan bir karakter okumaya teşebbüs eder. Ve bir uygun karakteri bekler. F1 gibi non-ASCII tuşlar ile ilk çağrıda 0’a eşit kod geri döner ve ikincide basılan tuşun tarama kodu çağrılır. 06h fonksiyonundan farklı olarak, bu fonksiyon klavye tamponu boşsa tuş basılana kadar bekler. Ctrl-C gibi kontrol karakterleri açıklanmamıştır. Fonksiyon 06h – Standart Girdi Aygıtından Denetimle Karakter Girdisi Alır: Bu fonksiyon klavye tamponundan bir karakter okumaya teşebbüs eder. Ve bir uygun karakteri bekler. F1 gibi non-ASCII tuşlar ile ilk çağrıda 0’a eşit kod geri döner ve ikincide basılan tuşun tarama kodu çağrılır. Bu fonksiyon klavyeden standart girdi aygıtı kadar uzun bir şekilde okur. Eğer yol <dosya ya da <aygıt aktif şeklindeyse, karakterler dosya ya da aygıttan okunur. Ctrl-C gibi kontrol karakterleri açıklanmamıştır. Register Çağrı Değeri AH 08h Dönen Değer AL ASCII kod Fonksiyon 0ah – Standart Girdi Aygıtından Echo’yla tamponlanmış karakter girer: Bu fonksiyon tampondan karakter stringi okur. RETURN’e basıldığında girdi sonlandırılır. Ctrl-C (program iptali) ve Ctrl-P (Printer da eko) hariç karakter kodlarından önce “^” simgesi getirilir. (Örneğin Ctrl-R, ^R). Tamponun ilk byte’ı girdinin maksimumunu gösterir ve ikinci byte asıl uzunluktur. Bu yüzden tampon maksimum uzunluk+2 byte içerir. Bu fonksiyon klavyeden standart girdi aygıtındaki kadar uzun okur. Eğer yönelimi <dosya ya da <aygıt aktif şeklindeyse, bütün karakterler dosya ya da aygıttan okur. Register Çağrı Değeri AH 0ah DX Dönen Değer tampon ofseti 185 DS tampon segmenti Fonksiyonu 0bh – Standart Girdi Aygıtının Durumunu Denetler: Bu fonksiyon karakter standart girdi aygıtı yoluyla alındığında tanımlanır. Bu fonksiyon klavyeye standart girdi aygıtı kadar uzun erişir. Yönelim <dosya ya da <aygıt aktif şeklindeyse bütün karakterler dosya ya da aygıttan okunur. Register Çağrı Değeri AH 0bh AL Dönen Değer 00h=hiçbir karakter uygun değil ffh= bir karakter uygun Fonksiyon 3fh – Dosya / Aygıt Okur: Bu fonksiyon klavyeden tampon içine bir ya da daha çok karakter okur. Genellikle klavye (CON) tutucu 0 atanmıştır. Register Çağrı Değeri AH 3fh Dönen Değer AX BX CX hata kodu byte numarası tutucu okunan byte’ların numarası DX tampon ofsetini okur DS tampon segmentini okur error if <>0 * Elde ayarlanmışsa sistem hata kodu, yada o anda okunan byte’ların numarası. J-1-2 BIOS İnterrupt INT 16h: Fonksiyon 00h – Gelecek Karakteri Okur: Bu fonksiyon klavye tamponunun dışından gelecek karakteri okurve uygun getirme işaretçisi günceller. Fonksiyon gelecek tuşu bekler. Register Çağrı Değeri AH 00h Dönen Değer tarama kodu AL ASCII kodu Fonksiyon 01h – Tampon Durumunu Tanımlar: 186 Bu fonksiyon klavye tamponunun durumunu tanımlar. Ve karakter uygun olduğunda gösterir. 00h fonksiyonunun aksine, klavye işaretçisi güncellenmemiştir. Register Çağrı Değeri AH 01h Dönen Değer tarama kodu AL ASCII kodu Sıfır 0= karakter uygun 1= hiçbir karakter uygun değil Fonksiyon 02h – Shift Durumunu Tanımlar: Bu fonksiyon klavye bayrağı 0040:0017’yi denetleyerek shift tuşlarının durumunu tanımlar. Register Çağrı Değeri AH 02h Dönen Değer AL shift durumu *) *) bkz. J-1-4 Fonksiyon 03h – Yazma Aralığını ve Duraklamayı Ayarlar: Bu fonksiyon AT ve MFII klavyelerin yazma aralığını ve duraklamayı ayarlar. Register Çağrı Değeri AH 03h BL tipmatik aralığı 1) BH duraklama 2) Dönen Değer 2 ) L-21 Fonksiyon 05h – Klavye Tamponunda Karakter ve tarama Kodunu Geri Yazar: Bu fonksiyon bir ASCII karakter yazar ve tarama kodunun tarama tamponuna geri gömderir. Ve bir tuş basılmasını benzetir. Register Çağrı Değeri AH 05h Dönen Değer 187 AL durum *) CH tarama kodu CL ASCII kodu *) 00h=O.K. 01h = klavye tamponu dolu Fonksiyon 10h – Uzatılmış Tampondan bir Karakter Okur: Bu fonksiyon uzatılmış (MFII) klavyeden bir karakter okur. Bu fonksiyon 00h’a banzer ama uzatılmış klavyenin kodlarını destekler. Bu yeni fonksiyonun kodlarıiçin önkod byte’ı 0eh geçilir. Yerine 00h değeri gelir. Böylece yeni tuşlar geleneksel olandan ayrılabilir. Register Çağrı Değeri AH 10h AL Dönen Değer tarama kodu ASCII kodu Fonksiyon 11h – Uzatılmış Klavye İçin Tampon Durumunu Tanımlar: Bu fonksiyon uzatılmış klavye için tampon durumunu tanımlar. Bu fonksiyon 01h fonksiyonuna benzer ancak uzatılmış klavye kodlarını destekler. Bu yeni fonksiyonun kodlarıiçin önkod byte’ı 0eh geçilir. Yerine 00h değeri gelir. Böylece yeni tuşlar geleneksel olandan ayrılabilir. Register Çağrı Değeri AH 11h AL Dönen Değer tarama kodu ASCII kodu Sıfır 0= karakter uygun 1= hiçbir karakter uygun değil Fonksiyon 12h – Uzatılmış Klavye için Shift Durumunu Tanımlar: Bu fonksiyon klavye bayrağı 0040:0017 ve 0040:0018’i denetleyerek SHIFT tuşlarının durumunu tanımlar. Bu fonksiyon 11h fonksiyonuyla uyuşur. Ancak uzatılmış klavye için ek SHIFT tuşlarını destekler. Register Çağrı Değeri AH 12h AL Dönen Değer 2. Shift durumu byte’ı 1) 1. Shift durumu byte’ı 2) 1) bkz. J-1-5 2) bkz. J-1-4 J-1-4 – Birinci Shift Durum Byte’ı: 188 J-1-4 – Birinci Shift Durum Byte’ı: J-2 – Mouse İnterrupt 33h: Mouse ve Mouse sürücüsü 33h kesmesi yoluyla erişilebilirler. J-2-1 – INT 33h’ın Fonkiyonları: Bu fonksiyon mouse var olduğunda tanımlanır. Ve mouse sürücüsünün standart ayarlarını getirir. BX register’ı içinde uygun mause düğmelerinin numarası geri döner. Register AX BX Çağrı Değeri 00h Dönen Değer durum 1) Mouse Düğmeleri 2) 1) 1= mouse var; 0=hiçbir mouse yok 2) 2= iki düğme (Microsoft); 3= üç düğme 189 Fonksiyon 01h – Mouse İmlecini Gözterir / İmleç Bayrağının Artımı: Bu fonksiyon imleç bayrağını arttırır. Bayrak 0’a eşitse mouse’un imleci ekran üzerinde görünür. Normalde imleç bayrağı –1 değerindedir. Register AX Çağrı Değeri Dönen Değer 01h Fonksiyon 02h – Mouse İmlecini Temizler / İmleç Bayrağının Azalımı: Bu fonksiyon imleç bayrağını bir azaltır. Böylece Mouse’un imleci ekrandan temizlenir. Bayrak 0’a eşitse mouse’un imleci ekran üzerinde görünür. Normalde imleç bayrağı –1 değerindedir. Register AX Çağrı Değeri Dönen Değer 02h Fonksiyon 03h- Mouse Düğmelerini ve Mouse İmleç Konumunu Tanımlar: Bu fonksiyon mouse düğmelerinin güncel durumunu ve mouse imlecinin ekran üzerindeki güncel konumunu tanımlar. Register AX Çağrı Değeri Dönen Değer 03h BX düğme byte’ı *) CX imleç konumunun X-değeri DX imleç konumunun Y-değeri *) bkz. J-2-2 : (1=düğme basımına uydurma, 0=düğme bırakımına uydurma) Fonksiyon 04h – Mouse’un İmleç Konumunu Ayarlar: Bu fonksiyon mouse imlecinin ekran üzerindeki konumunu ayarlar. Register AX Çağrı Değeri Dönen Değer 04h CX imleç konumunun X-değeri DX imleç konumunun Y-değeri Fonksiyon 05 – Mouse’un Basılan Düğme Numarasını Ve Mouse’un İmleç Konumuınu Tanımlar: Bu fonksiyon kesin mouse düğmesinin hangi sıklıkla basıldığını ve son tıklamada mouse imlecinin ekranın neresinde olduğunu tanımlar. Register AX Çağrı Değeri 05h Dönen Değer düğme byte’ı 1) 190 BX mouse düğmesi 2) sayaç değeri 3) CX imleç konumunun X-değeri DX imleç konumunun Y-değeri 1) bkz – J-2-2 (1=düğme basımına uydurma, 0=düğme bırakımına uydurma) 2) 1= sol düğme denetle 2= sağ düğme denetle 4= orta düğme denetle 3) tıklamaların numarası (0 dan 32’ye, 767) Fonksiyon 06h – Bırakılan Mouse Düğmesini ve Mouse İmleç Konumunu Belirtir: Bu fonksiyon kesin mouse düğmesinin son araştırmadan bu yana hangi sıkılıkla bırakıldığını ve son bırakmada mouse imlecinin ekranın neresinde olduğunu belirtir. Register AX BX Çağrı Değeri 06h mouse düğmesi 2) CX Dönen Değer düğme byte’ı 1) sayaç değeri 3) imleç konumunun X-değeri DX imleç konumunun Y-değeri 1) bkz – J-2-2 (1=düğme basımına uydurma, 0=düğme bırakımına uydurma) 2) 1= sol düğme denetle 2= sağ düğme denetle 4= orta düğme denetle 3) tıklamaların numarası (0 dan 32’ye, 767) Fonksiyon 07h – Mouse İmleci İçin Yatay Kenarlık Tanımlar: Bu fonksiyon mouse imleci hareketinin yatay kenarlıklarını belirler. Mouse imleci bunun dışına çıkamaz. Mouse daha uzağa giderse, böylece fonksiyon 08h ile birlikte mouse imleci için bir pencere tanımlayabilirsiniz. Register AX Çağrı Değeri Dönen Değer 07h BX CX sol kenarlık DX sağ kenarlık Fonksiyon 08h – Mouse imleci İçin Dikey Kenarlık Tanımlar: Bu fonksiyon mouse imleci için dikey kenarlık tanımnlar. Mouse imleci bunun dışına çıkamaz. Mouse daha uzağa giderse, böylece fonksiyon 07h ile birlikte mouse imleci için bir pencere tanımlayabilirsiniz. Register AX Çağrı Değeri Dönen Değer 08h BX CX üst kenarlık 191 DX alt kenarlık Fonksiyon 09h – Grafik Modda Mouse İmlecinin Tanımları: Bu fonksiyon mouse imlecinin grafik modda şeklini ve davranışını tanımlar. Ekran ve imleç maskesi tampon içinde bu düzende desteklenir. Eylem noktası göreceli mouse imlecinin konumunun bir sorgusunda geri dönen değer olan üst sol köşesi olarak tanımlanır. olarak tanımlanır. Register AX Çağrı Değeri Dönen Değer 09h BX yatay eylem noktası *) CX dikey eylem noktası *) DX maske tampon ofseti ES maske tampon segmenti *) değerlerin aralığı : -16....+16 Fonksiyon 0ah – Mouse İmleci Text Modda Tanımlar: Bu fonksiyon mouse imlecinin şeklini ve davranışını tanımlar. Register AX Çağrı Değeri Dönen Değer 0ah BX mouse imleç tipi 1) CX ekran maskesi DX imleç maskesi 3) 2) 1) 0= yazılım mouse imleç 1= donanım mouse imleç 2) yazılım mouse imleç ekran maske kodu , donanım mouse imleç ; mouse imlecin ilk tarama çizgisi 3) yazılım maske imleç ; imleç maske kodu 4) donanım mouse imleç ; mouse imlecinin son tarama çizgisi Fonsiyon 0bh – Mouse’un Hareket Saycını Okur: Bu fonksiyon mouse’un hareket sayacını okur. Ve son son fonksiyon çağrısından bu yana ne kadar uzağa hareket ettiğini beliritir. Bir Sayaç değeri 1/250 veya 0,13mm’ye eşittir. Register AX Çağrı Değeri Dönen Değer 0bh CX DX yatay sayaç değeri *) dikey sayaç değeri *) *) değerlerin aralığı - -32768 ..... +327767 192 Fonksiyon 0ch – Kullanıcı Prosedürü için Çağrı Maskesi Tanımlar: Bu fonksiyon uzun çağrı yoluyla mouse sürücüsünün bir kullanıcı tanımlı prosedür çağrısı için durumları tanımlar. Register AX Çağrı Değeri Dönen Değer 0ch CX çağrı maskesi *) DX prosedür ofseti ES prosedür segmenti Fonksiyon 0fh – Piksel Oranını Tanımlar: Bu fonksiyon her pikelin piksel piksel oranını tanımlar. Yatay standart değeri 8’e, dikey ise 16’ya eşittir. Register AX Çağrı Değeri Dönen Değer 0fh CX yatay oran *) DX dikey oran *) *) değerlerin aralığı 1.......32,767 K – Grafik Bağdaştırıcılara Erişim: - DOS fonksiyonları DOS’un 21h kesmesiyle çağırılırlar. 193 - Sistem BIOS grafik bağdaştırıcının text ve grafik modda standart fonksiyonlarını içerir. EGA ve VGA dah fazla güçlü bağdaştırıcı mantık kontrolleri ile BIOS uzantılarına sahiptir. Bunlar yani text ve grafik formtları içinde karakter ve grafik çıktıları içindir. K-1 . DOS Fonksiyonları: Fonksiyon 02h – Karakter Çıktı: Bu fonksiyon standart çıktı aygıtından bir karakter çıktı verir. (genellike CON) Karakter kodu 07h (zil), 08h (backspace), 09h (tab), 0ah (çizgi besleme) ve 0dh (taşıma döngüsü) kontrol karakterlerinden önce gelir. Ve BIOS uydurma sürecini yürütür. Register AX DL Çağrı Değeri Dönen Değer 02h ASCII karakter kodu Fonksiyon 06h – Satandart Çıktı Aygıtlarına Denetimsiz Olarak Karakter Çıktı Verir: Bu fonksiyon standart çıktı aygıtından bir karakter çıktı verir. (genellike CON). Eğer yönelim <dosya ya da <aygıt aktif ise bütün karakterler dosya ya da aygıttan çıktı alınır. Ctrl-C gibi DOS kontrol karakterleri açıklanmamıştır. Ama yalnızca aktarılır. Karakter kodlar 07h (zil), 08h (backspace), 09h (tab), 0ah (çizgi besleme) ve 0dh (taşıma döngüsü) BIOS tarafından tanınır ve açıklanırlar. Register Çağrı Değeri AH 06h DL Dönen Değer ASCII karakter kodu Fonksiyon 09h – String Çıktı: Bu fonksiyon standart çıktı aygıtına string çıktı verir (genellike CON). String “$ (ASCII kod 36) karakteriyle sonlandırılmalıdır.” . Ctrl-C gibi DOS kontrol karakterleri açıklanmamıştır. Ama yalnızca aktarılır. Karakter kodlar 07h (zil), 08h (backspace), 09h (tab), 0ah (çizgi besleme) ve 0dh (taşıma döngüsü) BIOS tarafından tanınır ve açıklanırlar. Register Çağrı Değeri Dönen Değer 194 AH 09h DX string ofseti DS string segmenti AL Fonksiyon 40h – Dosya / Aygıt Yazar : Bu fonkiyon tutucunun açıklamasıyla bir string çıktı verir. Tutucu standart çıktı aygıtı için 1’e eşittir. Eğer standart çıktı aygıtı CON ise ekran üzerine bir ya da daha çok çıktı almak istiyorsanız. CON’u dosya/aygıt açma fonksiyonuyla yazma erişimi için açmanız gerekiyor. Register Çağrı Değeri AH 40h AX BX CX DX DS Dönen Değer hata kodu / byte numarası *) tutucu (01h) çıktı byte’larının numarası yazma tamponu ofseti yazma tamponu segment Elde hata kodu *) Elde ayarlı ise sistem hata kodu, ya da güncel yazılan byte’ların numarası K-2 – BIOS İnterrupt 10h – Sistem BIOS’un Standart Fonksiyonları: Listelenmiş fonksiyonlar anakart üzerinde sistem BIOS içinde yürütülmüşlerdir. Fonksiyon 00h – Video Modu Ayarlar: Bu fonksiyon uygun değerlerle modu ve grafik çipinin kontrol register’ını yükleyerek kesin video modunu ayarlar. Bir 00h fonksiyonu çağrısından sonra, imleç 0 çizgisindedir., sütun 0, palet standart renklere getirilir ve ekran temizlenir. Register Çağrı Değeri AH 00h AL Dönen Değer video modu *) *) her video RAM katmanı 195 Fonksiyon 01h – İmleç Boyutunu Ayarlar: Bu fonksiyon text modda imleç boyutunu ayarlar. Eğer tarama çizgisinin başlangıç değeri bitiş değerinden büyükse, bölünmüş imleç görünür. Eğer tarama çizgilerinin değeri aktif video modundaki karakter kutusunda verilen aralığın dışındaysa her bir imleç görüntülenmez. İmleç parametreleri BIOS’un veri alanında (40:60h) saklıdır. CGA için standart ayarlar: tarama çizgisi başlangıç= 6 ; taram çizgisi sonu = 7; MDA için tarama çizgisi başlangıcı=11; tarama çizgisi sonu=12 ‘dir. Register Çağrı Değeri AH 01h CH CL Dönen Değer imlecin tarama çizgisi başlangıcı 1) imlecin tarama çizgisi sonu 2) 1) bit 17 ayrılmış (=0); bit 6-5:00=normal 01= imleç görüntülenmümiş 2) bit 7-5 ayrılmış (=0); bit 4-0=tarama çizgisi sonu Fonksiyon 02h – İmleç Konumunu Ayarlar: Bu fonksiyon aktif ekran sayfasında imleç konumunu ayarlar. Ekran sayfasının gösterimde olması gerekir. Gizli sayfa adreslenebilir. Text Modda text imleci bu bölgede görülebilir. Grafik modda görünmez arta kalır. Ancak Nerede olduğu koordinatları tanımlanır. Örneğin nokta ayarlanabilir. Bu fonksiyon imleç koordinatlarını 40:50h’ta saklar. Register Çağrı Değeri AH 02h BH Dönen Değer ekran sayfası DH sıra DL sütun Fonksiyon 03h- İmleç Konumunu Okur: Bu fonksiyon aktif ekran sayfasında imleç konumunu belirtir. Ekran sayfası görünümde olmamalıdır. Zaten gizli sayfa adreslenebilir. Bu fonksiyon imleç koordinatlarını 40:50h’tan okur. Register Çağrı Değeri AH 03h BH Dönen Değer ekran sayfası CH imleç – tarama çizgisi başlangıcı CL imleç – tarama çizgisi sonu DH satır DL sütun 196 Fonksiyon 04h – Işık Kalemi Konumunu Okur: (Text / Grafik) Bu fonksiyon ışık kaleminin konumunu ve durumunu belirtir. Bu günlerde ışık kaleminin yerini mouse ve iz topu almıştır. Register Çağrı Değeri AH 04h Dönen Değer durum 1) BH piksel sütunu (grafik mod) CH piksel çizgisi 0-199 (grafik mod) CL imleç çizgisi (0 – xxx2) (gm) DH sıra (text mod) DL sütun (text mod) 1) 00h = ışık kalemi açma anahtarı 01h= anahtar kapalı, koordinatlar geçerli 2) 200 çizgiden büyük çizgilerle mod için (xxx 200) Fonksiyon 05h – Ekran Sayfası Seçer (Text / Grafik): Bu fonksiyon aktif ekran sayfası’nı belirtir. (görünene sayfa). Uygun ekran sayfasının numarası video mod olarak korunur, ve grafik bağdaştırıcı kullanılır. Register Çağrı Değeri AH 05h AL Dönen Değer ekran sayfası Fonksiyon 06h – Pencereyi Yukarı Kaydırır (Text / Grafik): Bu fonksiyon ekran üzerinde bir pencere tanımlar ve pencere içerğini belirtilmiş sıra numarasını yukarı kaydırır. AL=00h ile pencere temizlenir. Boş sıralar pencerenin dibinde görünür ve boş (blank) karakterlerle doldurulur. Bu boş karakterler BH registerından atanmış özelliktedir. Register Çağrı Değeri Dönen Değer AH AL 06h kaydırılan satırların numarası BH boş sıralrın özelliği CH pencerenin üst sırası CL pencerenin sol sütunu DH pencerenin alt sırası DL pencerenin sağ sütunu Fonksiyon 07h – Pencereyi Yukarı Kaydırır (Text / Grafik): 197 Bu fonksiyon ekran üzerinde bir pencere tanımlar ve pencere içerğini belirtilmiş sıra numarasını aşağı kaydırır. AL=00h ile pencere temizlenir. Boş sıralar pencerenin dibinde görünür ve boş (blank) karakterlerle doldurulur. Bu boş karakterler BH registerından atanmış özelliktedir. Register Çağrı Değeri AH 07h AL Dönen Değer kaydırılan satırların numarası BH boş sıralrın özelliği CH pencerenin üst sırası CL pencerenin sol sütunu DH pencerenin alt sırası DL pencerenin sağ sütunu Fonksiyon 08h – Ekrandan Karakter / Özellik Okur (Text / Grafik): Bu fonksiyon güncel imleç konuumundan karakter okur. Muhtemelen imleci arzu ettiğiniz konuma getirmeliniz (fonksiyon 02h ile). Text modda bu fonksiyon sadece karakter kodu geri döndürmez ancak karakter özelliğidir. Grafik modda karakter matrisi belirtilmiş imleç konumunda karakter koduyla belirtilmiş aktif karaktr tablosuyla karşılaştırılmıştır. Eğer matris deseni tablodaki karakterle karşılaşmazsa fonksiyon bir 00h kodu geri döndürür. Register Çağrı Değeri AH 08h Dönen Değer(yalnızca text modda) karakter özelliği AL BL karakter kodu ekran sayfası Fonksiyon 09h – Ekran Üzerinde Karakter Özellik Yazar (Text / Graifk): Bu fonksiyon bir karakter yazar, güncel imleç konumunu başlatır, ve süreç CX kadar döner. İmleç konumuınu bununla değiştirmiştir. BL özelliği belirtir. Ve grafik modda karakterin önalan rengi yazılmış olabilir. Eğer karakterler grafik modda yazılmışsa ve BL’nin bit 7’si ayarlanmışsa karakterin karakter matrisi XOR – lanmış video RAM’ın içeriğiyşa bu bölgeye yazılmış olabilir. Register Çağrı Değeri AH 09h AL karakter kodu BH ekran sayfası BL CX Dönen Değer(yalnızca text modda) karakter özelliği ya da önalan rengi tekrarlanmışsa numarası Fonk 0ah – Ekran Üzerine Karakter Yazar (Text / Grafik): 198 Bu fonksiyon bir karakter yazar, güncel imleç konumunu başlatır, ve süreç CX kadar döner. İmleç konumuınu bununla değiştirmiştir.Eğer karakterler grafik modda yazılmışsa ve BL’nin bit 7’si ayarlanmışsa karakterin karakter matrisi XOR – lanmış video RAM’ın içeriğiyşa bu bölgeye yazılmış olabilir. Register Çağrı Değeri AH 09h AL karakter kodu BH ekran sayfası CX Dönen Değer(yalnızca text modda) tekrarlanmışsa numarası Fonksiyon 0bh – Renk Paletini Ayarlar (Grafik): Bu fonksiyon CGA’nın orta çözünürlüğü için renkleri ayarlar. BH register değeri olarak saklanır. BL register farklı anlamdadır. Palet Değiştirilerek görüntülenmiş ekranın rengi ani olarak değiştirilebilir. Ve kullanıcı yanıp sönen ekran izlenimi alır. Register Çağrı Değeri AH 0bh BH BL BH = 00h -Dönen Değer(yalnızca text modda) 00h renk 0-31 *) *) mod 4,5, artalan rengi BL’ye eşit mod 0,1,2,3 : kenarlık rengi BL’ye eşit mod 6,11 : önalan rengi BL’ye eşit Register Çağrı Değeri AH 0bh BH BL BH = 01h -Dönen Değer(yalnızca text modda) 01h palet *) *) 00h : palet = yeşil (1), kırmızı (2), sarı (3) 01h : palet = cyan (1), magenta (2), beyaz (3) Fonksiyon 0ch – Ekran Üzerine Piksel Yazar (Grafik): Bu fonksiyon ekran üzerinde arzu edilen bölgeye bir piksel yazar. AL register’ının bit 7’si bit2i tersine çevirme hizmeti verir. AL içindeki bit, renk adreslenmiş bölgede güncel yerleşmiş 199 piksel ile XOR’lanmıştır. Eğer tekrar aynı çeşit piksel yazacaksanız, ekrandan kalkmalı. Böylece nesneler ekranda görünüş olarak hareket etmiştir. Register AH Çağrı Değeri 0ch AL renk BH ekran sayfası *) CX piksel sütunu DX Dönen Değer piksel çizgisi *) yalnızca video mod birden fazla sayfa desteklerse gerekli Fonksiyon 0dh – Ekrandan Piksel Okur (Grafik): Bu fonksiyon ekran üzerinde kesin bölgede bir piksel okur. Register Çağrı Değeri AH 0dh Dönen Değer AL okunana pikselin rengi BH ekran sayfası *) CX piksel sütunu DX piksel çizgisi *) yalnızca video mod birden fazla sayfa desteklerse gerekli Fonksiyon 0fh – Video Durumunu Belirtir. (Text / Grafik): Bu fonksiyon güncel video modunu ve video durumunu belirtir. Register AH Çağrı Değeri Dönen Değer 0fh sütunların numarsı AL BH video mod (40:49h’dan) aktif ekran sayfası (40:62h ‘dan) Fonksiyon 13h – String Yazar (Text / Grafik): Bu fonksiyon ekran üzerine geniş stringler yazar. AL register’ının 0 ve 1 bitleri fonksiyonun davranışını belirtir. String karakter kodlarını ve farklı olarak karakter özelliklerini ya da yalnızca karakter özelliklerini içerir. İkinci durumda BL register’ının içinde kullnıldığında özellik geçilmiştir. Şekil TM3 K3 – BIOS İnterrupt INT 10h – EGA/VGA BIOS için EK Fonksiyonlar: Fonksiyon 00h – video Modunu Ayarlar: Bu fonksiyon uygun değerlerle grafik yongasının mod ve kontrol register’ını yükleyerek EGA ve VGA’nın kein video modunu ayarlar. Yüksek çözünürlüklü EGA ve VGA bağgaştırıcı kartlar sizin bağdaştırıcı kartınızda ayarlama için bulabileceğiniz text ve grafik modu için çözünürlük 200 bollluğuna sahiptir. 00h fonksiyon çağrısından sonra imleç çizgi 0’da sütun 0, palet standart renklere ayarlı, ekran temizlenmiş. S-1 Fonksiyon 10h – Palet Register’ını Ayarlar: Bu fonksiyon EGA ve VGA’nın palet register’ını ayarlar. EGA ile 64 farklı renk olasıdır. VGA ile 218 = 262,144 renk olasıdır. K4 – BIOS İnterrupt INT 10h – Ek SVGA BIOS Fonksiyonlar: Fonksiyon 4fh – SVGA BIOS Fonksiyonları Çağrısı : Alt Fonksiyon 00h – SVGA bilgisini Belirtir: Bu fonksiyon SVGA BIOS varken belirtilir ve bu güncel durumdur. M-1 Alt Fonksiyon 01h – SVGA Mod Bilgisini Belirtir: Bu fonksiyon bir 256 byte tamponun içinde SVGA moduna bakarak bilgi geri döndürür. M-2 Alt Fonksiyon 02h – SVGA Modunu Ayarlar: Bu fonksiyon SVGA modlarından birine VESA tarafından tanımlı olarak ayarlar. M-3 Alt Fonksiyon 03h – SVGA Modunu Belirtir: Bu fonksiyon güncel SVGA modunu belirtir. M-3a * Alt Fonksiyon 04h – SVGA Video durumu Kaydet / Eski Haline Getir: Bu fonksiyon SVGA BIOS’un durumunu kaydeder ya da eski haline getirir. 201 ASSEMBLY PROGRAM ÖRNEKLERİ 1.BÖLÜM: TITLE PROGRAMMING ASSIGNMENTS 6-1 PAGE 55,80 COMMENT | PROGRAM : PA6-1.ASM PROGRAMMER : KADIR GECKIN DATE : 23/11/2000 BU PROGRAM EKRANA BIR MESAJ YAZAR DOSUN 21H KESMESINI VE 2 NOLU FONKSIYONUNU KULLANIR (DL ICINDE KARAKTER GOSTER) INPUT PARAM'S :NONE OUTPUT PARAM'S:NONE RETURNS TO DOS,UPON COMPLETION | ;=================================================================== STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') STACK ENDS ;=================================================================== DATA SEGMENT PARA PUBLIC 'DATA' MY_MSG DB 13,10 DB 'high there!',13, 10, 10 DB 'This is a test.',13, 10, 0 ENDS DATA ;=================================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH DS MOV PUSH MOV MOV ASSUME AX, 0 AX AX, DATA DS, AX DS:DATA MOV SI, OFFSET MY_MSG LP_BEG: CMP JE MOV DL, [SI] INC SI DL, 0 LP_END CALL DSPLY_CHR JMP LP_BEG LP_END: RET MAIN ENDP 202 ;================================================================== DSPLY_CHR PROC NEAR PUSH MOV INT POP AX AH, 2 21H AX RET DSPLY_CHR CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSINGMENT 6-2 PAGE 55,80 COMMENT | PROGRAM PROGRMMER DATE : PA6_2.ASM : KADIR GECKIN : 23/11/2000 BU PROGRAM DOSUN 21H KESMESINI KULLANARAK, EKRANA BIR MESAJ YAZAR, 2 NOLU FONKSIYON (DL NIN ICINDE GOSTER) GENEL DENGE YERINE REPEAT WHILE KULLANILMISTIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS,UPON COMPLETION | ;======================================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;======================================================================== DATA MY_MSG DATA SEGMENT PARA PUBLIC 'DATA' DB DB DB 13, 10 'High there! ',13, 10, 10 'This is a test.',13, 10, 0 ENDS ;======================================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH DS AX, 0 AX 203 MOV AX, DATA MOV DS, AX ASSUME DS:DATA MOV SI, OFFSET MY_MSG MOV INC DL, [SI] SI LP_BEG: CMP JE DL, 0 LP_END CALL MOV INC JMP DSPLY_CHR DL, [SI] SI LP_BEG LP_END: RET MAIN ENDP ;-------------------------------------------------------------------DSPLY_CHR PROC NEAR PUSH MOV INT POP AX AH, 2 21H AX RET DSPLY_CHR ENDP CODE ENDS END COMMENT | MAIN TITLE PROGRAMMING ASSIGNMENTS PAGE 55,80 PROGRAM : PA6-3.ASM PROGRAMMER : KADIR GECKIN DATE : 23/11/2000 BU PROGRAM DOSUN 21H KESMESINI VE 2 NOLU FONKSIYONUNU KULLANARAK BIR ALT PROSEDUR ICINDE EKRANA B˜R MESAJ YAZAR(DL ICINDE KARAKTE GOSTER) INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS,UPON COMPLETION | ;====================================================================== STACK SEGMENT PARA STACK 'STACK' 204 DB 64 DUP ('*STACK*') STACK ENDS ;====================================================================== DATA SEGMENT PARA PUBLIC 'DATA' MSG1 MSG2 MSG3 MSG4 DB DB DB DB DB DATA ENDS 13, 10, 'Hight there!', 13, 10, 0 'This is a test.', 13, 10, 10, 0 'Are you having fun yet???', 13, 10, 0 'We will be if this works!..........' 13, 10, 10, 0 ;====================================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME MAIN PROC CS:CODE, SS:STACK FAR PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS, AX ASSUME DS:DATA MOV CALL MOV CALL MOV CALL MOV CALL SI, OFFSET DSPLY_MSG SI, OFFSET DSPLY_MSG SI, OFFSET DSPLY_MSG SI, OFFSET DSPLY_MSG MSG1 MSG2 MSG3 MSG4 RET MAIN ENDP ;===================================================================== DSPLY_MSG PROC NEAR PUSH PUSH LP_BEG: MOV INC CMP JE DX SI DL, [SI] SI DL, 0 LP_END CALL DSPLY_CHR JMP LP_BEG LP_END: POP POP RET SI DX 205 DSPLY_MSG ENDP ;==================================================================== DSPLY_CHR PROC NEAR PUSH MOV INT POP AX AH, 2 21H AX RET DSPLY_CHR ENDP CODE ENDS END MAIN 206 ASSEMBLY PROGRAM ÖRNEKLERİ BÖLÜM-2: COMMENT | CONSOLE.MLB KADIR GE€KIN I/O KONSOLU ICIN MACRO KUTUPHANESI TO USE : CONSOLE.MLB PROGRAMIN ANA CIZGI BASLANGICINI OLUSTURUR. EGER MASM NIN 1-4 SURUMUNU KULLANIYORSANIZ. INCLUDELIB EMIRLERI ALTINDA TANIMLANIR LINK SIRASINDA KUTUPHANE OLARAK CONSOLE.LIB BELIRTILIR. BU KUTUPHANEDE OLAN MACROLAR LOCATE ROW,COL DSPLY_CHR CHAR BDSPLY_CHR CHAR,ATT,PAGE SELECT_PAGE PAGE SCROLL LINES,UL_ROW,UL_COL,LR_ROW, LR_COL,LR_COL,ATT SCROLL_DN LINES,UL_ROW,UL_COL,LR_ROW,LR_COL,ATT CLS UL_ROW,UL_COL,LR_ROW,LR_COL,ATT SET_VID_MODE MODE,PAGE,COL GET_VID_STAT MODE,PAGE,COLS WRITE_PIXEL ROW,COL,PIXEL_VALUE READ_PIXEL ROW,COL,PIXEL_VALUE DSPLY_STR STR_OFF,TRAILER DSPLY_STRL STR_OFF BDSPLY_STR STR_OFF,TRAILER,ATT,PAGE BDSPLY_STRL STR_OFF,TRAILER INPUT_CHR CHAR BINPUT_CHR CHAR,SCAN CHECK_KBRD STATUS CHECK_KEYS KEYS FLUSH_KBRD DSLPY_IMMED_STR STRING TRAILER BDISLPY_IMMED STRRING,TRAILER,ATT,PAGE INPUT_STR BUFF_OFF,MAX_LEN,TRAILER INPUT_STR BUFF_OFF,MAX_LEN BINPUT_STR BUFF_OFF,MAX_LEN,TRAILER,ECHO_ATT,ECHO_PAGE BINPUT_STRL BUFF_OFF,MAX_LEN,TRAILER,ECHO_ATT,ECHO_PAGE CNV_UNS_STR CNV_UNS_STRL CNV_INT_STR CNV_INT_STRL CNV_STR_UNS CNV_STRL_UNS CNV_STR_INT CNV_STRL_INT CNV_STR_LEN BUFF_OFF,UNS_INT,BASE,TRAILER BUFF_OFF,UNS_INT,BASE BUFF_OFF,UNS_INT,BASE,TRAILER BUFF_OFF,UNS_INT,BASE BUFF_OFF,UNS_INT,BASE,TRAILER BUFF_OFF,UNS_INT,BASE BUFF_OFF,UNS_INT,BASE,TRAILER BUFF_OFF,UNS_INT,BASE STR_OFF,STR_LEN,TRAILER | COMMENT INCLUDELIB CONSOLE | LOCATE MACRO================================================= CONSOLE.LIB ˜€˜NDE $LOCATE ALTPROSEDURU KULLANRAK 207 ˜MLEC˜ EKRAN šZER˜NDE KONUMLANDIRIR. INPUT PARAMETER: ROW = ROW TO POSITION TO (0-20) SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT:0 COL = COLUMN TO POSITION TO (0-79) SIZE : BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT:0 OUTPUT PARAMETERS: NONE | LOCATE MACRO ROW,COL IFNDEF $LOCATE ETRN $LOCATE:NEAR ENDIF PUSH SUB BP SP,2 MOV BP,SP IFB <ROW> MOV BYTE PTR [BP+0],0 ELSE MOV BYTE PTR [BP+0],ROW ENDIF IFB <COL> MOV BYTE.PTR[BP+1],0 ELSE MOV BYTE PTR [BP+1],COL ENDIF CALL $LOCATE POP BP ENDM COMMENT | DSPLY_CHR MACRO =============================== CONSOLE LIB'IN ICINDE $DSPLY_CHR PROISEDURUNU KULLANARAK EKRANA TEKBIR KARAKTER BASAR INPUT PARAMETERS: CHAR = CHARACTER TO DISPLAY SIZE: BYTE ADRESSING MODES: REGISTER OR IMMEDIATE OUTPUT PARAMETERS: NONE | DSPLY_CHR MACRO CHAR IFNDEF $DSPLY_CHR EXTRN $DSPLY_CHR:NEAR ENDIF PUSH BP DEC SP MOV BP,SP MOV BYTE PTR [BP],CHAR CALL $DSPLY_CHR POP BP ENDM 208 COMMENT | LOCATE.ASM KADIR GECKIN IMLECI SAYFADA KONUMLANDIRAN ALTPROSEDUR 10H KESMESINI (BIOS VIDEO SERVICES),OPERATION 02H INPUT PARAMETERS: ROW TO POSITION TO SIZE:BYTE COLUMN TO POSITON TO SIZE:BYTE LOCATION:[BP+1] OUTPUT PARAMETERS: NONE | TITLE PAGE DATA $LOCATE.ASM 55,80 SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CODE $LOCATE PROC NEAR PUBLIC $LOCATE $LOCATE CODE PUSH PUSH PUSH AX BX DX MOV MOV MOV MOV DH, DL, AH, BH, INT 10H POP POP POP DX BX AX RET 2 [BP+0] [BP+1] 02H 0 ENDP ENDS END 209 COMMENT | $DSP_CHR.ASM KADIR GECKIN DOSUN CAGIRMA ISLEVINI, 02 NOLU FONKSIYONUNU KULLANARAK EKRANA BIR KARAKTER BASAN ALTPROSEDUR INPUT PARAMETERS: CHARACTER TO DISPLAY SIZE: BYTE LOCATE: [BP+0] OUTPUT PARAMATERS: NONE | TITLE PAGE DATA $DSP_CHR.ASM 55,80 SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CODE $DSPLY_CHR PROC NEAR PUBLIC $DSPLY_CHR $DSPLY_CHR CODE PUSH PUSH AX DX MOV MOV DL, [BP+0] AH, 02H INT 21H POP POP DX AX RET 1 ENDP ENDS END TITLE PROGRAM ASSIGNMENT 7-1 PAGE 55,80 COMMENT | PROGRAM : PA7-1.ASM PROGRAMMER: KADIR GECKIN 210 DATE : 26/11/2000 PROGRAM DISPLAY_CHR BLOGUNU KULLANARAK EKRANDA BIR MESAJ GOSTERIR... INPUT PARAM'S : NONE OUTPUT PARAM'S: NONE RETURN TO DOS,UPON,COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT ======================================================== DATA SEGMENT PARA PUBLIC 'DATA' MY_MSG DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB DATA ENDS CODE SEGMENT PARA PUBLIC 'CODE' MAIN LP_BEG: 13, 10, 10, 10, 10, 10 'Once there was an assembly-language' 'student...', 13, 10, 10 'First, his program wouldn', "'" 't assemble.', 13, 10 'When it finally assembled, it wouldn', "'" "'",'t link', 13, 10 'When it finally linked, it locked up the', "'" 'machine', 13, 10, 10 'He beat his head and wailed and moaned' 13, 10 ' "I hate assembly language! ' 'Why did ever take this class?"' 13, 10, 10, 10, 10 'But finally it ran...', 13, 10, 10 'He leaped for joy and wooped and' 'hollered,', 13, 10 ' "It works! It works! I', "'" 'm so glad I took this class!".' 13, 10, 10, 10, 0 ASSUME CS:CODE, SS:STACK PROC FAR PUSH DS MOV PUSH MOV MOV ASSUME AX, 0 AX AX,DATA DS,AX DS:DATA MOV SI, OFFSET MY_MSG MOV AL, [SI] 211 INC SI CMP AL, 0 JE LP_END DSPLY_CHR AL JMP LP_BEG LP_END: RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 7-2 PAGE 55,80 PROGRAM : PA7_2.ASM PROGRAMMER : KADIR GE€KIN DATE : 26/11/2000 COMMENT | PROGRAM LOCATE VE DSPLY_CHR BLOKLARINI KULLANRAK IMLECI EKRANDA KONUM LANDIRIR VE BIRKAC MESAJ YAZAR INPUT PARAMS'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS,UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ;STACK SEGMENT ====================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT ======================================================= DATA SEGMENT PARA PUBLIC 'DATA' MSG_1 MSG_2 MSG_3 DB DB DB DATA ENDS 'Hi there', 0 'This is a test.', 0 'This another test.', 0 ;CODE SEGMENT ======================================================= CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV DS AX, 0 212 PUSH AX MOV AX, DATA MOV DS, AX ASSUME DS:DATA LOCATE 10 MOV SI, OFFSET MSG_2 CALL DISPLAY_STR LOCATE , 71 MOV SI, OFFSET MSG_1 CALL DISPLAY_STR LOCATE 24,30 MOV SI, OFFSET MSG_3 CALL DISPLAY_STR LOCATE RET MAIN ENDP ;-----------------------------------------------------------------------DISPLAY_STR PROC PUSH PUSH NEAR AX SI LP_BEG: MOV INC AL,[SI] SI CMP AL,0 JE LP_END DSPLY_CHR AL JMP LP_BEG LP_END: POP SI POP AX RET DISPLAY_STR ENDP CODE ENDS END MAIN 213 ASSEMBLY PROGRAM ÖRNEKLERİ BOLUM-3: COMMENT | BDSPLY_CHR MACRO ============================================= PROGRAM CONCOLE.LIB'IN ICINDE $BDSPLY_CHR PROSEDURUNU KULLANARAK EKRANA OZELLIGIYLE BIRLIKTE BIR KARAKTER BASAR INPUT PARAMETERS: CHAR = CHARAKTER TO DISPLAY SIZE:BYTE ADDRESSING MODES: REGISTER OR IMMEDIATE ATT = ATTRIBUTE FOR DISPLAY SIZE:BYTE ADDRESSING MODES: REGISTER OR IMMEDITE DEFAULT: NORMAL VIDEO(07H) N=NORMAL(07H) R=REVERSE(07H) B=BLINK(87H) - MONOCHROME ONLY H=HIGHLIGHT (OFH) OTHER=BINARY ATTRIBUTE PAGE = PAGE TO DISPLAY TO SIZE:BYTE ADDRESSING MODES:REGISTER OR IMMEDIATE DEFAULT:0 OUTPUT PARAMETERS: NONE | BDSPLY_CHR MACRO CHAR, ATT, PAGE IFNDEF $BDSPLY_CHR EXTRN $BDSPLY_CHR:NEAR ENDIF PUSH SUB MOV MOV BP SP, 3 BP, SP BYTE PTR [BP+2],CHAR IFB <PAGE> MOV BYTE PTR [BP+0],0 ELSE MOV BYTE PTR [BP+0],PAGE ENDIF IFB <ATT> MOV BYTE PTR [BP+1],07H ELSE IFIDN <ATT>,<N> MOV BYTE PTR [BP+1],07H ELSE IFIDN <ATT>,<R> MOV BYTE PTR [BP+1],87H ELSE IFNDN <ATT>,<H> MOV BYTE PTR [BP+1],ATT 214 ENDIF ENDIF ENDIF ENDIF ENDIF CALL $BDSPLY_CHR POP BP ENDM COMMENT | SELECT_PAGE MACRO ================================== CONSOLE.LIB'˜N ˜€˜NDE $SELECT_PAGE PROSEDURU ˜LE ETK˜N EKRAN SAYFASININ SE€ER INPUT PARAMETERS: PAGE= NEW ACTIVE PAGE TO BE DISPLAYED SIZE:BYTE ADRESSING MODES: REGISTER OR IMMEDIATE OUPUT PARAMETERS: NONE | SELECT_PAGE MACRO PAGE IFNDEF $SELECT_PAGE EXTRN $SELECT_PAGE:NEAR ENDIF PUSH DEC BP SP MOV BP,SP MOV BYTE PTR [BP+0],PAGE CALL $SELECT_PAGE POP BP ENDM COMMENT | SCROLL MACRO ======================================== CONSOLE.LIB ICINDE $SCROLL PROSEDURUNU KULANARAK EKRANDA B˜R KAUYDIRMA PENCERESI OLUSTURUR -YUKARI ITER INPUT PARAMETERS: LINES : NUMBER OF LINES TO SCROLL SIZE: BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:1 UL_ROW: UPPER LEFT ROW OF WINDOW SCROLL (0-24) SIZE:BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:0 UL_COL: UPPER LEFT COLUMN OF WINDOW TO SCROLL (0-79) SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT:0 LR_ROW: LOWER RIGHT ROW WINDOW TO SCROLL (0-24) SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT:24 215 LR_COL: LOWER_RIGHT COLUMN OF WINDOW TO SCROLL (0-79) SIZE:BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:79 ATT: ATTRIBUTE FOR FILL SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT: 07H (NORMAL VIDEO) N= NORMAL (07H) R= REVERSE (07H) B= BLINK (87H) - MONOCHROME ONLY H= HIGHLIGHT (OFH) OTHER = BINARY ATTRIBUTE OUTPUT PATRAMETERS: NONE: | SCROLL MACRO LINES,UL_ROW,UL_COL,LR_ROW,LR_COL,ATT IFNDEF $SCROLL EXTRN $SCROLL:NEAR ENDIF PUSH BP SUB SP,6 MOV BP,SP IFB <LINES> MOV BYTE PTR [BP+0],1 ELSE MOV BYTE PTR [BP+0],LINES ENDIF IFB <UL_ROW> MOV BYTE PTR [BP+1],0 ELSE MOV BYTE PTR [BP+1],UL_ROW ENDIF IFB <UL_COL> MOV BYTE PTR [BP+2],0 ELSE MOV BYTE PTR [BP+2],UL_COL ENDIF IF <LR_ROW> MOV BYTE PTR [BP+3],24 ELSE MOV BYTE PTR [BP+3],LR_ROW ENDIF IFB <LR_COL> MOV BYTE PTR [BP+4],79 ELSE MOV BYTE PTR [BP+4],LR_COL ENDIF IFB <ATT> MOV BYTE PTR [BP+5],07H ELSE MOV BYTE PTR [BP+5],07H 216 ENDIF ELSE IFIDN <ATT>,<R> MOV BYTE PTR [BP+5],70H ELSE IFDN <ATT>,<P> MOV BYTE PTR [BP+5],87H ELSE IFIDN <ATT>,<H> MOV BYTE PTR [BP+5],OFH ELSE MOV BYTE PTR [BP+5],ATT ENDIF ENDIF ENDIF ENDIF ENDIF CALL $SCROLL POP BP ENDM COMMENT | SCROLL_DN MACRO ========================================== CONSOLE.LIB ICINDEKI $SCROLL_DOWN PROSEDURUNU KULLANRAK EKRANDAKI PENCEREYI ASAGI DORU KAYDIRIR. INPUT PARAMETERS LINES: NUMBER OF LINES TO SCROLL SIZE: BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:1 UL_ROW: UPPER LEFT ROW OF WINDOW TO SCROLL (0-24) SIZE:BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:0 UL_COL: UPPER LEFT COLUMN OF WINDOW OT SCROLL (0-79) SIZE:BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:0 LR_ROW: LOWER RIGHT ROW OF WINDOW TO SCROLL (0-24) SIZE:BYTE ADDRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:24 LR_COL: LOWER RIGHT COLUMN OF WINDOW TO SCROLL (0-79) SIZE:BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:79 ATT: ATTRIBUTE FOR FILL SIZE:BYTE ASDRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:07H (NORMAL VIDEO) N = NORMAL (O7H) R = REVERSE (07H) B = BLINK (87H) -MONOCHROME ONLY H = HIGHLIGHT (OFH) OTHER = BINARY ATTRIBUTE 217 OUTPUT PARAMETERS: NONE | SCROLL_DN MACRO LINES,UL_ROW,UL_COL,LR_ROW,LR_COL,ATT IFNDEF $SCROLL_DN EXTRN $SCROLL_DN:NEAR ENDIF PUSH SUB MOV BP SP,6 BP,SP IFB <LINES> MOV BYTE PTR [BP+0],1 ELSE MOV BYTE PTR [BP+0],LINES ENDIF IFB <UL_ROW> MOV BYTE PTR [BP+1],0 ELSE MOV BYTE PTR [BP+1],UL_ROW ENDIF IFB <UL_COL> MOV BYTE PTR [BP+2],0 ELSE MOV BYTE PTR [BP+2],UL_COL ENDIF IFB <LR_ROW> MOV BYTE PTR [BP+3],24 ELSE MOV BYTE PTR [BP+3],LR_ROW ENDIF IFB <LR_COL> MOV BYTE PTR [BP+4],79 ELSE MOV BYTE PTR [BP+4],LR_COL ENDIF IFB <ATT> MOV BYTE PTR [BP+5],07H ELSE IFIDN <ATT>,<N> MOV BYTE PTR [BP+5],07H ELSE IFIDN <ATT>,<R> MOV BYTE PTR [BP+5],OFH ELSE MOV BYTE PTR [BP+5],ATT ENDIF ENDIF ENDIF ENDIF ENDIF CALL $SCROLL_DN POP BP ENDM 218 COMMENT | CLS MACRO ============================================== SCROLL MACRO YU KULLANARAK EKRANDAKI PENCEREYI TEMIZLE INPUT PARAMETERS: UL_ROW: UPPER LEFT ROW OF WINDOW TO CLEAR (0-24) BYTE,REGISTER OR IMMEDIATE DEFAULT= 0 UL_COL : UPPER LEFT COLUMN OF WINDOW TO TO CLEAR (0-79) BYTE,REGISTER OR IMMEDIATE DEFAULT=0 LR_ROW : LOWER RIGHT ROW OF WINDOW TO CLEAR (0-24) BYTE,REGISTER OR IMMEDIATE DEFAULT=24 LR_COL : LOWER RIGHT COLUMN OF WINDOW TO CLEAR (0-79) BYTE,REGISTER OR IMMEDIATE DEFAULT =79 OUTPUT PARAMETERS: NONE | CLS MACRO UL_ROW,UL_COL,LR_ROW,LR_COL,ATT SCROLL 0,<UL_ROW>,<UL_COL>,<LR_ROW>,<LR_COL>,<ATT> ENDM COMMENT | SET_VID_MODE MACRO===================================== SETS THE VIDEO MODE USES $SET_VID_MODE PROCEDURE IN CONSOLE.LIB INPUT PARAMETERS: MODE = NEW VIDEO MODE SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE ALLOWED MODES ARE AS FOLLOWS: Mode reso- Colors Text/ adapters (AL) lution Graphics 00H 40/25 16 Text Color Burst off 01H 40/25 16 Text 02H 80/25 16 Text Color burst off 03H 80/25 16 Text 04H 320/200 16 Graphics 05H 320/200 4 Graphics Color burst off 06H 640/200 2 Graphics 07H 80/25 2* Text ODH 640/200 16 Graphics OEH 640/200 16 Graphics OFH 640/350 2* Graphics 10H 640/350 16 Graphics CGA,EGA,MCGA,VGA CGA,EGA,MCGA,VGA CGA,EGA,MCGA,VGA CGA,EGA,MCGA,VGA CGA,EGA,MCGA,VGA CGA,EGA,MCGA,VGA CGA,EGA,MCGA,VGA MDA,EGA,VGA EGA,VGA EGA,VGA EGA,VGA EGA,VGA 219 11H 12H 13H 640/480 640/480 320/200 16 Graphics 16 Graphics 16 Graphics MCGA,VGA VGA MCGA,VGA * = Monochrome monitor only OUTPUT PARAMETERS NONE | SET_VID_MODE MACRO MODE IFNDEF $SET_VID_MODE:NEAR ENDIF PUSH BP DEC SP MOV BP,SP MOV BYTE PTR [BP+0],MODE CALL $SET_VID_MODE POP BP ENDM COMMENT | GET_VID_STAT MACRO ======================================= CONSOLE.LIB ICINDE $GET_VID_STAT PROCEDURE IUN CONSOLE.LIB GUNCEL VIDEO KIPINE CAGIRIR. BIOSTAN ETKIN SAYFA VE KARAKTER SUTUNUNU €A¦IRIR INPUT PARAMETERS: NONE OUTPUT PARAMETERS: MODE = CURRENT VIDEO MODE OPTIONAL PARAMETERS SIZE:BYTE ADRESSING MODES: REGISTER ONLY PAGE = ACTIVE PAGE OPTIONAL PARAMETER SIZE: BYTE ADRESSING MODES:REGISTER ONLY COLS = VIDEO MODE RETURNED BY BIOS OPTIONAL PARAMETERS SIZE:BYTE ADRESSING MODES:REGISTER ONLY SEE SET_VID_MODE FOR A LIST OF VIDEO MODES | GET_VID_STAT MACRO MODE,PAGE,COLS IFNDEF $GET_VID_STAT EXTRN $GET_VID_STAT:NEAR ENDIF PUSH BP SUB SP,3 MOV BP,SP CALL $GET_VID_STAT IFNB <MODE> 220 MOV MODE,[BP+0] ENDIF IFNNB <PAGE> MOV PAGE, [BP+1] ENDIF MOV COLS, [BP+2] ENDIF ADD SP,3 POP BP ENDM COMMENT | WRITE_PIXEL MACRO ========================================== CONSOLE.LIB ICINDE $WRITE_PIXEL PROSEDURU ILE GRAFIK MODUNDA BOS SAYFAYA BIR PIKSEL YAZAR INPUT PARAMETERS: ROW: ROW OF PIXEL (Y COORDINATE) SIZE: WORD ADDRESSING MODES:REGISTER OR IMMEDIATE COLUMN OF PIXEL (X COORDINATE) SIZE:WORD ADRESSING MODES:REGISTER OR IMMEDIATE WRITE_PIXEL: MACRO ROW,COL,PIXEL_VALUE IFNDEF $WRITE_PIXEL EXTRN $WRITE_PIXEL ENDIF PUSH SUB MOV MOV MOV BP SP,5 BP,SP WORD PTR [BP+0],ROW WORD PTR [BP+4],PIXEL_VALUE CALL $WRITE_PIXEL POP BP ENDM COMMENT | READ_PIXEL MACRO =========================================== CONSOLE.LIB ICINDE $READ_PIXEL PROSEDURU ILE GRAFIK MODDA SAYFADAN BIR PIXEL OKUR INPUT PARAMETERS: ROW = ROW OF PIXEL TO READ (Y COORDINATE) SIZE:WORD ADRESSING MODES:REGISTER OR IMMEDIATE OUTPUT PARAMETERS: PIXEL_VALUE = PIXEL VALUE AT COL, ROW SIZE: BYTE ADDRESSING MODES: REGISTER ONLY | READ_PIXEL MACRO ROW,COL,PIXEL_VALUE IFNDEF $READ_PIXEL EXTRN $READ_PIXEL:NEAR ENDIF PUSH BP SUB SP,4 221 MOV MOV MOV BP,SP WORD PTR [BP+0],ROW WORD_PIXEL MOV PIXEL_VALUE,BYTE,BYTE PTR [BP+3] INC POP SP BP ENDM COMMENT | DSPLY_STR MACRO ========================================== CONSOLE.LIB $DSPLY_STR PROSEDURU ILE DOS SAYFASI UZERINDE DATA SEGMENTTE TANIMLI ARKA ARKAYA NORMAL BIR OZELLIKLE BIR STRING GOSTRERIR. INPUT PARAMETERS: STR_OFF = OFFSET OF STRING WORD,REGISTR OR IMMEDIATE TRAILER = CHARACTER USED TO MARK END OF STRING BYTE,REGISTER OR IMMEDIATE DEFUALT =NUL CHARACTER OUTPUT PARAMETERS: NONE | DSPLY_STR MACRO STR_OFF,TRAILER IFNDEF $DSPLY_STR EXTRN $DSPLY_STR:NEAR ENDIF PUSH BP SUB SP,3 MOV MOV BP,SP WORD PTR [BP+0],STR_OFF IFB <TRAILER> MOV BYTE PTR [BP+2],0 ELSE MOV BYTE PTR [BP+2],TRAILER ENDIF CALL $DSPLY_STR POP ENDM BP COMMENT | DSPLY_STRL MACRO ========================================= CONSOLE.LIB ICINDE $DSPLY_STRL ILE DATA SEGMENTTE TANIMLI 1 BYTE UZUNLUGUNDA BIR STRING GOSTERIR DOS ˜LE SAYFA ARASINDA NORMAL OZELLIGIYLE GOSTERIR INPU PARAMETERS: STR_OFF = OFFSET OF STRING WORD,REGISTER OR IMMEDIATE OUTPUT PARAMETERS : NONE | 222 DSPLY_STR MACRO STR_OFF IFNDEF $DSPLY_STRL EXTRN $DSPLY_STRL:NEAR ENDIF PUSH SUB BP SP,2 MOV MOV BP,SP WORD PTR [BP],STR_OFF CALL $DSPLY_STRL POP BP ENDM COMMENT | BDSPLY_STR MACRO ========================================= CONSOLE.LIB ˜€˜NDE $BDSPLY_STR PROSEDURU ˜LE DATA SEGMENTTE TANIMLI SIRALI ™ZELL˜¦E ˜Z˜N VEREN VE BIOS ˜LE HERHANGI B˜R SAYFA ARASINDA B˜R STR˜NG G™STER˜R INPUT PARAMETERS: STR_OFF = OFFSET OF STRING WORD, REGISTER OR IMMEDITATE TRAILER = CHARACTER USED USED TO MARK AND STRING BYTE,REGISTER OR IMMEDIATE DEFAULT = NUL CHARACTER ATT = ATTRIBUTE FOR DISPLY SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT: NORMAL VIDEO (07H) N = NORMAL (07H) R = REVERSE (70H) B = BLINK (87H) - MONOCHROME ONLY H = HIGHTLIGHT (OFH) OTHER =BINARY ATTRIBUTE PAGE = PAGE TO DISPLAY TO SIZE :BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:0 OUTPUT PARAMETERS: NONE | BDSPLY_STR MACRO STR_OFF,TRAILER,ATT,PAGE IFNDEF $BDSPLY_STR:NEAR ENDIF PUSH SUB BP SP,5 MOV MOV BP,SP WORD PTR [BP+0],STR_OFF IFB <TRAILER> MOV BYTE PTR [BP+2],0 ELSE MOV BYTE PTR [BP+2],TRAILER ENDIF IFB <ATT> 223 MOV BYTE PTR [BP+3],07H ELSE IFIDN <ATN>,<N> MOV BYTE PTR [BP+3],07H ELSE IFIDN <ATT>,<R> MOV BYTE PTR [BP+3],07H ELSE IFIDN <ATT>,<B> MOV BYTE PTR[BP+3],0FH ELSE MOV BYTE PTR [BP+3],87H ELSE IFIDN <ATT>,<H> MOV BYTE PTR [BP+3],0FH ELSE MOV BYTE PTR [BP+3],ATT ENDIF ENDIF ENDIF ENDIF ENDIF IFB <PAGE> MOV BYTE PTR [BP+4],0 ELSE MOV BYTE PTR [BP+4],PAGE ENDIF CALL $BDSPLY_STR POP BP ENDM COMMENT | BDSPLY_STRL MACRO ====================================== CONSOLE.LIB ICINDE $DSPLY_STRL PROSEDURU ILE DATA SEGMENTTE TANIMLI BIR BYTE UZUNLUGUNDA BIR STRING GOSTERIR BIOS ILE HERHANGI BIR SAYFA ARASINDA BIR OZELLIK KABUL EDER INPUT PARAMETERS: STR_OFF = OFFSET OF STRING WORD,REGISTER OR IMMEDIATE ATT = ATTRIBUTE FOR DISPLAY SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT:NORMAL VIDEO (07H) N= NORMAL (07H) R= REVERSE (70H) B= BLINK (87H) - MONOCHROME ONLY H= HIGHLIGHT (0FH) OTHER = BINARY ATTRIBUTE PAGE = PAGE TO DISPLAY TO SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT:0 OUTPUT PARAMETERS : NONE | BDSPLY_STRL MACRO STR_OFF,ATT,PAGE 224 IFNDEF $BDSPLY_STRL:NEAR EXTRN $BDSPLY_STRL:NEAR ENDIF PUSH SUB BP SP,4 MOV MOV BP,SP WORD PTR [BP+0],STR_OFF IFB <ATT> MOV BYTE PTR [BP+2],07H ELSE IFIDN <ATT>,<N> MOV BYTE PTR [BP+2],07H ELSE IFIDN <ATT>,<R> MOV BYTE PTR [BP+2],70H ELSE IFIDN <ATT>,<B> MOV BYTE PTR [BP+2],87H ELSE IFIDN <ATT>,<H> MOV BYTE PTR [BP+2],OFH ELSE MOV BYTE PTR [BP+2],ATT ENDIF ENDIF ENDIF ENDIF ENDIF IFB <PAGE> MOV BYTE PTR [BP+3],0 ELSE MOV BYTE PTR [BP+3],PAGE ENDIF CALL $BDSPLY_STRL POP BP ENDM COMMENT | DSPLY_STRR MACRO CONSOLE.LIB ICINDE $DSPLY_STRR (B˜R SIRA PROSEDURU) ILE DATA SEGMENTTE KUYRUK ILE TANIMLI STRINGLERI SIRALI BIR OZEKILDE GOSTERIR NORMAL BIR OZELLIKLE DOS ILE SAYFA ARASINDA GOSTERIR. OUTPUT PARAMETERS: NONE | DSPLY_STRR MACRO STR_OFF,TRAILER IFNDEF $DSPLY_STRR EXTRN $DSPLY_STRR:NEAR ENDIF PUSH SUB MOV BP SP,3 BP,SP 225 MOV WORD PTR [BP+0],STR_OFF IFB <TRAILER> MOV BYTE PTR [BP+2],0 ELSE MOV BYTE PTR [BP+2],TRAILER ENDIF CALL $DSPLY_STRR POP BP ENDM COMMENT | BDSPLY_CHR MACRO ============================================= PROGRAM CONCOLE.LIB'IN ICINDE $BDSPLY_CHR PROSEDURUNU KULLANARAK EKRANA OZELLIGIYLE BIRLIKTE BIR KARAKTER BASAR INPUT PARAMETERS: CHAR = CHARAKTER TO DISPLAY SIZE:BYTE ADDRESSING MODES: REGISTER OR IMMEDIATE ATT = ATTRIBUTE FOR DISPLAY SIZE:BYTE ADDRESSING MODES: REGISTER OR IMMEDITE DEFAULT: NORMAL VIDEO(07H) N=NORMAL(07H) R=REVERSE(07H) B=BLINK(87H) - MONOCHROME ONLY H=HIGHLIGHT (OFH) OTHER=BINARY ATTRIBUTE PAGE = PAGE TO DISPLAY TO SIZE:BYTE ADDRESSING MODES:REGISTER OR IMMEDIATE DEFAULT:0 OUTPUT PARAMETERS: NONE | BDSPLY_CHR MACRO CHAR, ATT, PAGE IFNDEF $BDSPLY_CHR EXTRN $BDSPLY_CHR:NEAR ENDIF PUSH SUB MOV MOV BP SP, 3 BP, SP BYTE PTR [BP+2],CHAR IFB <PAGE> MOV BYTE PTR [BP+0],0 ELSE MOV BYTE PTR [BP+0],PAGE ENDIF 226 IFB <ATT> MOV BYTE PTR [BP+1],07H ELSE IFIDN <ATT>,<N> MOV BYTE PTR [BP+1],07H ELSE IFIDN <ATT>,<R> MOV BYTE PTR [BP+1],87H ELSE IFNDN <ATT>,<H> MOV BYTE PTR [BP+1],ATT ENDIF ENDIF ENDIF ENDIF ENDIF CALL $BDSPLY_CHR POP BP ENDM COMMENT | SELECT_PAGE MACRO ================================== CONSOLE.LIB'IN ICINDE $SELECT_PAGE PROSEDURU ILE ETKIN EKRAN SAYFASININ SECER INPUT PARAMETERS: PAGE= NEW ACTIVE PAGE TO BE DISPLAYED SIZE:BYTE ADRESSING MODES: REGISTER OR IMMEDIATE OUPUT PARAMETERS: NONE | SELECT_PAGE MACRO PAGE IFNDEF $SELECT_PAGE EXTRN $SELECT_PAGE:NEAR ENDIF PUSH DEC BP SP MOV BP,SP MOV BYTE PTR [BP+0],PAGE CALL $SELECT_PAGE POP BP ENDM COMMENT | SCROLL MACRO ======================================== CONSOLE.LIB ICINDE $SCROLL PROSEDURUNU KULANARAK EKRANDA BIR KAUYDIRMA PENCERESI OLUSTURUR -YUKARI ITER INPUT PARAMETERS: LINES : NUMBER OF LINES TO SCROLL SIZE: BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:1 UL_ROW: UPPER LEFT ROW OF WINDOW SCROLL (0-24) 227 UL_COL: LR_ROW: LR_COL: ATT: SIZE:BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:0 UPPER LEFT COLUMN OF WINDOW TO SCROLL (0-79) SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT:0 LOWER RIGHT ROW WINDOW TO SCROLL (0-24) SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT:24 LOWER_RIGHT COLUMN OF WINDOW TO SCROLL (0-79) SIZE:BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:79 ATTRIBUTE FOR FILL SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT: 07H (NORMAL VIDEO) N= NORMAL (07H) R= REVERSE (07H) B= BLINK (87H) - MONOCHROME ONLY H= HIGHLIGHT (OFH) OTHER = BINARY ATTRIBUTE OUTPUT PATRAMETERS: NONE: | SCROLL MACRO LINES,UL_ROW,UL_COL,LR_ROW,LR_COL,ATT IFNDEF $SCROLL EXTRN $SCROLL:NEAR ENDIF PUSH BP SUB SP,6 MOV BP,SP IFB <LINES> MOV BYTE PTR [BP+0],1 ELSE MOV BYTE PTR [BP+0],LINES ENDIF IFB <UL_ROW> MOV BYTE PTR [BP+1],0 ELSE MOV BYTE PTR [BP+1],UL_ROW ENDIF IFB <UL_COL> MOV BYTE PTR [BP+2],0 ELSE MOV BYTE PTR [BP+2],UL_COL ENDIF IF <LR_ROW> MOV BYTE PTR [BP+3],24 ELSE 228 MOV BYTE PTR [BP+3],LR_ROW ENDIF IFB <LR_COL> MOV BYTE PTR [BP+4],79 ELSE MOV BYTE PTR [BP+4],LR_COL ENDIF IFB <ATT> MOV BYTE PTR [BP+5],07H ELSE MOV BYTE PTR [BP+5],07H ENDIF ELSE IFIDN <ATT>,<R> MOV BYTE PTR [BP+5],70H ELSE IFDN <ATT>,<P> MOV BYTE PTR [BP+5],87H ELSE IFIDN <ATT>,<H> MOV BYTE PTR [BP+5],OFH ELSE MOV BYTE PTR [BP+5],ATT ENDIF ENDIF ENDIF ENDIF ENDIF CALL $SCROLL POP BP ENDM COMMENT | SCROLL_DN MACRO ========================================== CONSOLE.LIB ICINDEKI $SCROLL_DOWN PROSEDURUNU KULLANRAK EKRANDAKI PENCEREYI ASAGI DORU KAYDIRIR. INPUT PARAMETERS LINES: NUMBER OF LINES TO SCROLL SIZE: BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:1 UL_ROW: UPPER LEFT ROW OF WINDOW TO SCROLL (0-24) SIZE:BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:0 UL_COL: UPPER LEFT COLUMN OF WINDOW OT SCROLL (0-79) SIZE:BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:0 LR_ROW: LOWER RIGHT ROW OF WINDOW TO SCROLL (0-24) SIZE:BYTE ADDRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:24 LR_COL: LOWER RIGHT COLUMN OF WINDOW TO SCROLL (0-79) 229 ATT: SIZE:BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:79 ATTRIBUTE FOR FILL SIZE:BYTE ASDRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:07H (NORMAL VIDEO) N = NORMAL (O7H) R = REVERSE (07H) B = BLINK (87H) -MONOCHROME ONLY H = HIGHLIGHT (OFH) OTHER = BINARY ATTRIBUTE OUTPUT PARAMETERS: NONE | SCROLL_DN MACRO LINES,UL_ROW,UL_COL,LR_ROW,LR_COL,ATT IFNDEF $SCROLL_DN EXTRN $SCROLL_DN:NEAR ENDIF PUSH SUB MOV BP SP,6 BP,SP IFB <LINES> MOV BYTE PTR [BP+0],1 ELSE MOV BYTE PTR [BP+0],LINES ENDIF IFB <UL_ROW> MOV BYTE PTR [BP+1],0 ELSE MOV BYTE PTR [BP+1],UL_ROW ENDIF IFB <UL_COL> MOV BYTE PTR [BP+2],0 ELSE MOV BYTE PTR [BP+2],UL_COL ENDIF IFB <LR_ROW> MOV BYTE PTR [BP+3],24 ELSE MOV BYTE PTR [BP+3],LR_ROW ENDIF IFB <LR_COL> MOV BYTE PTR [BP+4],79 ELSE MOV BYTE PTR [BP+4],LR_COL ENDIF IFB <ATT> MOV BYTE PTR [BP+5],07H ELSE IFIDN <ATT>,<N> MOV BYTE PTR [BP+5],07H ELSE IFIDN <ATT>,<R> 230 MOV BYTE PTR [BP+5],OFH ELSE MOV BYTE PTR [BP+5],ATT ENDIF ENDIF ENDIF ENDIF ENDIF CALL $SCROLL_DN POP BP ENDM COMMENT | CLS MACRO ============================================== SCROLL MACRO YU KULLANARAK ELRANDAKI PENCEREYI TEMIZLE INPUT PARAMETERS: UL_ROW: UPPER LEFT ROW OF WINDOW TO CLEAR (0-24) BYTE,REGISTER OR IMMEDIATE DEFAULT= 0 UL_COL : UPPER LEFT COLUMN OF WINDOW TO TO CLEAR (0-79) BYTE,REGISTER OR IMMEDIATE DEFAULT=0 LR_ROW : LOWER RIGHT ROW OF WINDOW TO CLEAR (0-24) BYTE,REGISTER OR IMMEDIATE DEFAULT=24 LR_COL : LOWER RIGHT COLUMN OF WINDOW TO CLEAR (0-79) BYTE,REGISTER OR IMMEDIATE DEFAULT =79 OUTPUT PARAMETERS: NONE | CLS MACRO UL_ROW,UL_COL,LR_ROW,LR_COL,ATT SCROLL 0,<UL_ROW>,<UL_COL>,<LR_ROW>,<LR_COL>,<ATT> ENDM COMMENT | SET_VID_MODE MACRO===================================== SETS THE VIDEO MODE USES $SET_VID_MODE PROCEDURE IN CONSOLE.LIB INPUT PARAMETERS: MODE = NEW VIDEO MODE SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE ALLOWED MODES ARE AS FOLLOWS: Mode reso- Colors Text/ adapters (AL) lution Graphics 00H 40/25 16 Text Color Burst off 01H 40/25 16 Text CGA,EGA,MCGA,VGA CGA,EGA,MCGA,VGA 231 02H 80/25 16 Text Color burst off CGA,EGA,MCGA,VGA 03H 80/25 16 Text 04H 320/200 16 Graphics 05H 320/200 4 Graphics Color burst off 06H 640/200 2 Graphics 07H 80/25 2* Text ODH 640/200 16 Graphics OEH 640/200 16 Graphics OFH 640/350 2* Graphics 10H 640/350 16 Graphics 11H 640/480 16 Graphics 12H 640/480 16 Graphics 13H 320/200 16 Graphics CGA,EGA,MCGA,VGA CGA,EGA,MCGA,VGA CGA,EGA,MCGA,VGA CGA,EGA,MCGA,VGA MDA,EGA,VGA EGA,VGA EGA,VGA EGA,VGA EGA,VGA MCGA,VGA VGA MCGA,VGA * = Monochrome monitor only OUTPUT PARAMETERS NONE | SET_VID_MODE MACRO MODE IFNDEF $SET_VID_MODE:NEAR ENDIF PUSH BP DEC SP MOV BP,SP MOV BYTE PTR [BP+0],MODE CALL $SET_VID_MODE POP BP ENDM COMMENT | GET_VID_STAT MACRO ======================================= CONSOLE.LIB ICINDE $GET_VID_STAT PROCEDURE IUN CONSOLE.LIB GUNCEL VIDEO KIPINI CAGIRIR. BIOSTAN ETKIN SAYFA VE KARAKTER SUTUNUNU CAGIRIR INPUT PARAMETERS: NONE OUTPUT PARAMETERS: MODE = CURRENT VIDEO MODE OPTIONAL PARAMETERS SIZE:BYTE ADRESSING MODES: REGISTER ONLY PAGE = ACTIVE PAGE OPTIONAL PARAMETER SIZE: BYTE ADRESSING MODES:REGISTER ONLY COLS = VIDEO MODE RETURNED BY BIOS OPTIONAL PARAMETERS SIZE:BYTE ADRESSING MODES:REGISTER ONLY SEE SET_VID_MODE FOR A LIST OF VIDEO MODES | GET_VID_STAT MACRO MODE,PAGE,COLS 232 IFNDEF $GET_VID_STAT EXTRN $GET_VID_STAT:NEAR ENDIF PUSH BP SUB SP,3 MOV BP,SP CALL $GET_VID_STAT IFNB <MODE> MOV MODE,[BP+0] ENDIF IFNNB <PAGE> MOV PAGE, [BP+1] ENDIF MOV COLS, [BP+2] ENDIF ADD SP,3 POP BP ENDM COMMENT | WRITE_PIXEL MACRO ========================================== CONSOLE.LIB ICINDE $WRITE_PIXEL PROSEDURU ILE GRAFIK MODUNDA BOS SAYFAYA BIR PIKSEL YAZAR INPUT PARAMETERS: ROW: ROW OF PIXEL (Y COORDINATE) SIZE: WORD ADDRESSING MODES:REGISTER OR IMMEDIATE COLUMN OF PIXEL (X COORDINATE) SIZE:WORD ADRESSING MODES:REGISTER OR IMMEDIATE WRITE_PIXEL: MACRO ROW,COL,PIXEL_VALUE IFNDEF $WRITE_PIXEL EXTRN $WRITE_PIXEL ENDIF PUSH SUB MOV MOV MOV BP SP,5 BP,SP WORD PTR [BP+0],ROW WORD PTR [BP+4],PIXEL_VALUE CALL $WRITE_PIXEL POP BP ENDM COMMENT | READ_PIXEL MACRO =========================================== CONSOLE.LIB ICINDEE $READ_PIXEL PROSEDURU ILE GRAFIK MODDA SAYFADAN BIR PIXEL OKUR INPUT PARAMETERS: ROW = ROW OF PIXEL TO READ (Y COORDINATE) SIZE:WORD ADRESSING MODES:REGISTER OR IMMEDIATE 233 OUTPUT PARAMETERS: PIXEL_VALUE = PIXEL VALUE AT COL, ROW SIZE: BYTE ADRESSING MODES: REGISTER ONLY | READ_PIXEL MACRO ROW,COL,PIXEL_VALUE IFNDEF $READ_PIXEL EXTRN $READ_PIXEL:NEAR ENDIF PUSH SUB MOV MOV MOV BP SP,4 BP,SP WORD PTR [BP+0],ROW WORD_PIXEL MOV PIXEL_VALUE,BYTE,BYTE PTR [BP+3] INC POP SP BP ENDM COMMENT | DSPLY_STR MACRO ========================================== CONSOLE.LIB $DSPLY_STR PROSEDURU ILE DOS SAYFASI UZERINDE DATA SEGMENTTE TANIMLI ARKA ARKAYA NORMAL BIR OZELLIKLE BIR STRING GOSTRERIR. INPUT PARAMETERS: STR_OFF = OFFSET OF STRING WORD,REGISTR OR IMMEDIATE TRAILER = CHARACTER USED TO MARK END OF STRING BYTE,REGISTER OR IMMEDIATE DEFUALT =NUL CHARACTER OUTPUT PARAMETERS: NONE | DSPLY_STR MACRO STR_OFF,TRAILER IFNDEF $DSPLY_STR EXTRN $DSPLY_STR:NEAR ENDIF PUSH BP SUB SP,3 MOV MOV BP,SP WORD PTR [BP+0],STR_OFF IFB <TRAILER> MOV BYTE PTR [BP+2],0 ELSE MOV BYTE PTR [BP+2],TRAILER ENDIF CALL $DSPLY_STR POP ENDM BP 234 COMMENT | DSPLY_STRL MACRO ========================================= CONSOLE.LIB ICINDE $DSPLY_STRL ILE DATA SEGMENTTE TANIMLI 1 BYTE UZUNLUGUNDA BIR STRING GISTERIR DOS ˜LE SAYFA ARASINDA NORMAL OZELLIGIYLE GOSTERIR INPU PARAMETERS: STR_OFF = OFFSET OF STRING WORD,REGISTER OR IMMEDIATE OUTPUT PARAMETERS : NONE | DSPLY_STR MACRO STR_OFF IFNDEF $DSPLY_STRL EXTRN $DSPLY_STRL:NEAR ENDIF PUSH SUB BP SP,2 MOV MOV BP,SP WORD PTR [BP],STR_OFF CALL $DSPLY_STRL POP BP ENDM COMMENT | BDSPLY_STR MACRO ========================================= CONSOLE.LIB ICINDE $BDSPLY_STR PROSEDURU ILE DATA SEGMENTTE TANIMLI SIRALI OZELLIKLE OZEN VEREN VE BIOS ILE HERHANGI BIR SAYFA ARASINDA BIR STRING GOSTERIR INPUT PARAMETERS: STR_OFF = OFFSET OF STRING WORD, REGISTER OR IMMEDITATE TRAILER = CHARACTER USED USED TO MARK AND STRING BYTE,REGISTER OR IMMEDIATE DEFAULT = NUL CHARACTER ATT = ATTRIBUTE FOR DISPLY SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT: NORMAL VIDEO (07H) N = NORMAL (07H) R = REVERSE (70H) B = BLINK (87H) - MONOCHROME ONLY H = HIGHTLIGHT (OFH) OTHER =BINARY ATTRIBUTE PAGE = PAGE TO DISPLAY TO SIZE :BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT:0 OUTPUT PARAMETERS: NONE | BDSPLY_STR MACRO STR_OFF,TRAILER,ATT,PAGE IFNDEF $BDSPLY_STR:NEAR 235 ENDIF PUSH SUB BP SP,5 MOV MOV BP,SP WORD PTR [BP+0],STR_OFF IFB <TRAILER> MOV BYTE PTR [BP+2],0 ELSE MOV BYTE PTR [BP+2],TRAILER ENDIF IFB <ATT> MOV BYTE PTR [BP+3],07H ELSE IFIDN <ATN>,<N> MOV BYTE PTR [BP+3],07H ELSE IFIDN <ATT>,<R> MOV BYTE PTR [BP+3],07H ELSE IFIDN <ATT>,<B> MOV BYTE PTR[BP+3],0FH ELSE MOV BYTE PTR [BP+3],87H ELSE IFIDN <ATT>,<H> MOV BYTE PTR [BP+3],0FH ELSE MOV BYTE PTR [BP+3],ATT ENDIF ENDIF ENDIF ENDIF ENDIF IFB <PAGE> MOV BYTE PTR [BP+4],0 ELSE MOV BYTE PTR [BP+4],PAGE ENDIF CALL $BDSPLY_STR POP BP ENDM COMMENT | BDSPLY_STRL MACRO ====================================== CONSOLE.LIB ICINDE $DSPLY_STRL PROSEDURU ILE DATA SEGMENTTE TANIMLI BIR BYTE UZUNLUGUNDA BIR STRING GOSTERIR BIOS ILE HERHANGI BIR SAYFA ARASINDA BIR OZELLIK KABUL EDER INPUT PARAMETERS: STR_OFF = OFFSET OF STRING WORD,REGISTER OR IMMEDIATE ATT = ATTRIBUTE FOR DISPLAY SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT:NORMAL VIDEO (07H) 236 N= NORMAL (07H) R= REVERSE (70H) B= BLINK (87H) - MONOCHROME ONLY H= HIGHLIGHT (0FH) OTHER = BINARY ATTRIBUTE PAGE = PAGE TO DISPLAY TO SIZE:BYTE ADRESSING MODES:REGISTER OR IMMEDIATE DEFAULT:0 OUTPUT PARAMETERS : NONE | BDSPLY_STRL MACRO STR_OFF,ATT,PAGE IFNDEF $BDSPLY_STRL:NEAR EXTRN $BDSPLY_STRL:NEAR ENDIF PUSH SUB BP SP,4 MOV MOV BP,SP WORD PTR [BP+0],STR_OFF IFB <ATT> MOV BYTE PTR [BP+2],07H ELSE IFIDN <ATT>,<N> MOV BYTE PTR [BP+2],07H ELSE IFIDN <ATT>,<R> MOV BYTE PTR [BP+2],70H ELSE IFIDN <ATT>,<B> MOV BYTE PTR [BP+2],87H ELSE IFIDN <ATT>,<H> MOV BYTE PTR [BP+2],OFH ELSE MOV BYTE PTR [BP+2],ATT ENDIF ENDIF ENDIF ENDIF ENDIF IFB <PAGE> MOV BYTE PTR [BP+3],0 ELSE MOV BYTE PTR [BP+3],PAGE ENDIF CALL $BDSPLY_STRL POP BP ENDM COMMENT | DSPLY_STRR MACRO CONSOLE.LIB ICINDE $DSPLY_STRR (BIR SIRA PROSEDURU) ILE DATA SEGMENTTE KUYRUK ILE TANIMLI STRINGLERI SIRALI BIR SEKILDE GOSTERIR NORMAL BIR OZELLIKLE DOS ILE SAYFA ARASINDA GOSTERIR. 237 OUTPUT PARAMETERS: NONE | DSPLY_STRR MACRO STR_OFF,TRAILER IFNDEF $DSPLY_STRR EXTRN $DSPLY_STRR:NEAR ENDIF PUSH SUB MOV MOV BP SP,3 BP,SP WORD PTR [BP+0],STR_OFF IFB <TRAILER> MOV BYTE PTR [BP+2],0 ELSE MOV BYTE PTR [BP+2],TRAILER ENDIF CALL $DSPLY_STRR POP BP ENDM COMMENT | $BDSPLY_CH.ASM KADIR GE€KIN BIOS VIDEO HIZMETLERI KULLANILARAK,O9H VE 0EH ISLEMI ILE B˜R ALTYORDAM KULLANILARAK HERHANGI BIR EKRAN SAYFASINDA OZELLIGIYLE BIRLIKTE KARAKTER GOSTERIR. INPUT PARAMETERS: PAGE TO DISPLAY TO SIZE:BYTE LOCATION:[BP+0] ATTRIBUTE FOR DISPLAY SIZE:BYTE LOCATION:[BP+1] CHARACTER TO DISPLAY SIZE:BYTE LOCATION:[BP+2] OUTPUT PARAMETERS: NONE | TITLE $BDSP_CH.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'CODE' ASSUME DS:DATA DATA ENDS CODE SEGMENT BYTE PUBLIC'CODE' 238 ASSUME CS:CODE $BDSPLY_CHR PROC NEAR PUBLIC $BDSPLY_CHR PUSH PUSH PUSH AX BX CX MOV CMP JB CMP JBE CMP JE AL,[BP+2] AL,7 DSP_ATT AL,10 DSP_CHAR AL,13 DSP_CHAR DSP_ATT: MOV MOV MOV MOV INT AH,09H BH,[BP+0] BL,[BP+1] CX,1 10H DSP_CHAR: MOV AH,0EH MOV AL,[BP+2] MOV BH,[BP+0] INT 10H BDC_RET: POP POP POP RET CX BX AX 3 $BDSPLY_CHR ENDP CODE ENDS END COMMENT | KADIR $BDSP_SL.ASM GE€KIN DATA SEGMENTTE BIR BYTE LA SAKLI STRING GOSTERIR ALT YORDAM DSPLY_CHR YAPITAžI KULLANILARAK HERHANGI BIR SAYFAYA OZELLIGIYLE GOSTERIR. INPUT PARAMETERS: OFFSET OF THE STRING SIZE:WORD LOCATION:[BP+0] DISPLAY ATTRIBUTE SIZE:BYTE LOCATE:[BP+2] VIDEO PAGE SIZE:BYTE LOCATION:[BP+3] 239 OUTPUT PARAMETERS: NONE | INCLUDE CONSOLE.MLB TITLE PAGE DATA DATA CODE SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA ENDS SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CODE $BDSPLY_STRL PROC_NEAR PUBLIC $BDSPLY_STRL LP_BEG PUSH PUSH PUSH PUSH PUSH MOV MOV AX BX CX DX DH,[BP+2] BX,[BP+3] BX,[BP+0] MOV MOV JCXZ CL,[BX] CH,0 LP_END INC BX MOV AL,[BX] BDSPLY_CHR AL,DH,DL LP_BEG LOOP LP_END: $BDSP_SL.ASM 55,80 POP POP POP POP DX CX BX AX RET 4 $BDSPLY_STRL PROC NEAR PUBLIC $BDSPLY_STRL PUSH PUSH PUSH PUSH AX BX CX DX MOV MOV MOV DH,[BP+2] DL,[BP+3] BX,[BP+0] MOV CL,[BX] MOV CH,0 JCXZ LP_END LP_BEG: INC BX MOV AL,[BX] 240 BDSPLY_CHR LOOP AL,DH,DL LP_BEG POP POP POP POP DX CX BX AX RET 4 $BDSPLY_STRL ENDP CODE ENDP END COMMENT | $BDSP_ST.ASM KAD˜R GE€K˜N DATA SEGMENTTE KUYRUKLA SAKLI BIR STRING GOSTERIR ALTYORDAM BDSPLY_CHR YAPITAžI KULLANILARAK HERHANGI BIR SAYFAYA OZELLIGIYLE GOSTERIR INPUT PARAMETER: OFFSET OF THE STRING SIZE:WORD LOCATION:[BP+0] TRAILER CHARACTER SIZE:BYTE LOCATION:[BP+2] DISPLAY ATRIBUTE SIZE:BYTE LOCATION:[BP+4] OUTPUT PARAMETERS: NONE | INCLUDE CONSOLE.MLB TITLE $BDSP_ST.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CODE $BDSPLY_STR PROC NEAR PUBLIC $BDSPLY_STR PUSH PUSH AX BX PUSH BX MOV MOV MOV DH,[BP+3] DL,[BP+4] BX,[BP+0] 241 LP_BEG: CMP JE LP_END: MOV AL,[BX] AL,[BP+2] LP_END BDSPLY_CHR INC BX JMP LP_BEG POP POP POP DX BX AX RET 5 AL, DH, DL $BDSPLY_STR ENDP CODE ENDS END COMMENT | $BDSP_SL.ASM KAD˜R GE€K˜N DATA SEGMENTTE ARDIžIK OLARAK SAKLI STRING LERI SIRALI OLARAK GOSTEREN ALTYORDAM DSPLY_CHR YAPITAžI KULLANILIYOR INPUT PARAMETERS: OFFSET OF THE STRING STORED SIZE:WORD LOCATION:[BP+0] TRAILER CHARACTER SIZE: BYTE LOCATION:[BP+2] OUTPUT PARAMETERS: NONE | INCLUDE CONSOLE.MLB TITLE $DSP_SRR.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA CODE ENDS SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CODE $DSPLY_STRR PROC NEAR PUBLIC $DSPLY_STRR PUSH PUSH AX BX 242 MOV BX,[BP+0] MOV MOV CMP AH,[BP+2] AH,[BX] AL,AH JE DONE: DONE DSPLY_CHR AL INC BX DSPLY_STRR BX, AH POP POP BX AX RET 3 $DSPLY_STRR ENDP CODE ENDS END COMMENT | $DSP_STL.ASM KAD˜R GE€K˜N DATA SEGMENTTE BIR BYTE LA SAKLI BIR STRING GOSTERIR ALTYORDAM DSP_CHR YAPITASI KULLANILIR INPUT PARAMETERS: OFFSET OF THE STRING SIZE:WORD LOCATION:[BP+0] OUTPUT PARAMETERS: NONE | INCLUDE COLSOLE.MLB TITLE $DSP_STL.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA CODE ENDS SEGMENT BYTE PUBLIC 'CODE' ASSUME DS:CODE $DSPLY_STRL PROC NEAR PUBLIC $DSPLY_STRL PUSH PUSH PUSH AX BX CX MOV BX,[BP+0] MOV CL,[BX] 243 MOV CH,0 JCXZ LP_END LP_BEG: INC BX MOV AL,[BX] DSPLY_CHR AL LOOP LP_BEG LP_END: POP POP POP CX BX AX RET 2 $DSPLY_STRL ENDP CODE ENDS END COMMENT | $DSP_STR.ASM KADIR GE€KIN DATA SEGMENTTE KUYRUKTA SAKLI BIR STRING GOSTEREN ALTYORDAM DSPLY_CHR BULILDING BLOCK INPUT PARAMETERS: OFFSET OF THE STRING SIZE:WORD LOCATION:[BP+0] TRAILER CHARACTER SIZE:BYTE LOCATION:[BP+2] OUT PARAMETERS: NONE | INCLUDE CONSOLE.MLB TITLE PAGE $DSP_STR.ASM 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA CODE ENDS SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CODE $DSPLY_STR PROC NEAR PUBLIC $DSPLY_STR PUSH PUSH AX BX MOV BX,[BP+0] 244 LP_BEG: MOV AL,[BX] CMP AL,[BP+2] JE LP_END DSPLY_CHR AL INC BX JMP LP_BEG POP BX POP AX LP_END: RET 3 $DSPLY_STR CODE COMMENT ENDP ENDS END | $GET_VS.ASM KADIR GECKIN GUNCEL VIDEO DURUM BILGISINI BELIRLEYEN ALTYORDAM 10H KESMESI (BIOS VIDEO HIZMETI) KULLANILIR OFH INPUT PARAMETER: NONE OUTPUT PARAMETERS: CURRENT VIDEO MODE SIZE:BYTE LOCATION:[BP+0] ACTIVE PAGE SIZE:BYTE LOCATION:[BP+1] CHARACTER COLUMNS SIZE:BYTE LOCATION:[BP+2] | TITLE $GET_VS.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA CODE ENDS SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CODE $GET_VID_STAT PROC NEAR PUBLIC $GET_VID_STAT PUSH PUSH AX BX MOV INT AH,0FH 10H MOV MOV [BP+0],AL [BP+1],BH 245 MOV [BP+2],AH POP BX POP AX RET $GET_VID_STAT ENDP CODE ENDS END COMMENT | $SCROLL.ASM 10H KESMESI ILE (BIOS VIDEO HIZMETI) ISLEM 06H EKRAN PENCERESINI KAYDIRAN ALT ALTYORDAM INPUT PARAMETERS: # OF LINES TO SCROLL [BP+0],BYTE UPPER-LEFT ROW OF WINDOW [BP+1],BYTE LOWER-RIGHT ROW OF WINDOW [BP+3],BYTE ATTRIBUTE FOR FILL LINE(S) [BP+5],BYTE OUTPUT: NOTHING RETURNED SP RESTORED ON RETURN ALL REGISTERS RESTORED | TITLE PAGE DATA DATA CODE $SCROLL.ASM 55,80 SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA ENDS SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $SCROLL PROC NEAR PUBLIC $SCROLL PUSH PUSH PUSH PUSH AX BX CX DX MOV MOV MOV MOV MOV MOV INT AL,[BP] CH,[BP+1] CL,[BP+2] DH,[BP+3] DL,[BP+5] AH,06H 10H POP POP POP POP RET DX CX BX BX 6 246 $SCROLL ENDP CODE ENDS END COMMENT | $SCROL_D.ASM 10H KESMESINI (BIOS VIDEO SERVISI), KULLANARAK <ISLEM 07H> EKRAN PENCERESINI ASAGI KAYDIRAN ALTPROSEDUR INPUT PARAMETERS: # OF LINES TO SCROLL [BP+0],BYTE UPPER-LEFT ROW OF WINDOW [BP+1],BYTE UPPER-LEFT COLUMN OF WINDOW [BP+2],BYTE UPPER-RIGHT ROW OF WINDOW [BP+3],BYTE LOWER-RIGHT ROW OF WINDOW [BP+4],BYTE ATTRIBUTE FOR FILL LINES(S) [BP+5],BYTE OUTPUT: NOTHING RETURNED SP RESTORED ON RETURN ALL REGISTERS RESTORED | TITLE $SCROL_D.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA CODE ENDS SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $SCROLL_DN PROC NEAR PUBLIC $SCROLL_DN PUSH PUSH PUSH PUSH AX BX CX DX MOV MOV MOV MOV MOV MOV MOV INT AL,[BP] CH,[BP+1] CL,[BP+2] DH,[BP+3] DL,[BP+4] BH,[BP+5] AH,07H 10H POP DX POP CX POP BX 247 POP AX RET 6 $SCROLL_DN ENDP CODE ENDS END COMMENT | $SEL_PGE.ASM KADIR GECKIN BIOS VIDEO SERVISI ILE, ISLEM 05H KULLANILARAK ETKIN VIDEO SAYFASINI SECEN ALT YORDAM INPUT PARAMETERS: NONE | TITLE $SEL_PGE.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CODE $SELECT_PAGE PROC NEAR PUBLIC $SELECT_PAGE PUSH AX MOV MOV INT AH,05H AL,[BP+0] 10H POP RET AX 1 $SELECT_PAGE CODE COMMENT ENDP ENDS END | SET_VM.ASM KADIR GECKIN VIDEO KIPINI AYARLAYAN ALTYORDAM BIOS VIDEO SERVISINI KULLANIR, ISLEM 05H INPUT PARAMETERS: 248 NONE | TITLE $SET_VM.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CODE $SET_VID_MODE PROC NEAR PUBLIC $SET_VID_MODE PUSH AX MOV MOV INT AH,00H AL,[BP+0] 10H POP RET AX 1 $SET_VID_MODE ENDP CODE ENDS END COMMENT | $READ_PX.ASM KADIR GECKIN 1 NOLU SAYFADAN 1 PIXEL DESEN OKUYAN ALT YORDAM BIOS'UN VIDEO HIZMETI KULLANILIR, ISLEM 0DH INPUT PARAMETERS: ROW OF PIXEL (Y COORDINATE) SIZE:WORD LOCATION:[BP+0] COLUMN OF PIXEL (X COORDINATE) SIZE:WORD LOCATION:[BP+2] OUTPUT PARAMETER: PIXEL VALUE RETURNED BY BIOS SIZE:BYTE LOCATION:[BP+3] CLOSES 3 BYTES OF STACK HOLE:MACRO MOST CLOSE OTHER BYTE | 249 TITLE PAGE DATA DATA CODE $READ_PX.ASM 55,80 SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA ENDS SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CODE $READ_PIXEL PROC NEAR PUBLIC $READ_PIXEL PUSH PUSH PUSH PUSH AX BX CX DX MOV MOV MOV DX,[BP+0] CX,[BP+2] BH,0 MOV INT MOV BDC_RET: POP POP POP POP RET AH,0DH 10H [BP+3],AL DX CX BX AX 3 $READ_PIXEL ENDP CODE ENDS END COMMENT | $WRTE_PX.ASM KADIR GECKIN 1 NOLU SAYFAYA YAZBOZ SEKLINDE A PIKSEL DESEN BASAN ALTYORDAM BIOS VIDEO HIZMETI ILE, ISLEM 0CH INPUT PARAMETERS: ROW OF PIXEL (Y COORDINATE) SIZE:WORD LOCATION:[BP+0] COLUMN OF PIXEL (X COORDINATE) SIZE:WORD LOCATION:[BP+4] OUPTPUT PARAMETERS: NONE | TITLE $WRTE_PX.ASM PAGE 55,80 250 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CODE $WRITE_PIXEL PROC NEAR PUBLIC $WRITE_PIXEL PUSH PUSH PUSH PUSH AX BX CX DX MOV MOV MOV MOV MOV INT DX,[BP+0] CX,[BP+2] AL,[BP+4] BX,0 AH,0CH 10H BDC_RET: POP POP POP POP RET DX CX BX AX 5 $WRITE_PIXEL ENDP CODE ENDS END TITLE PROGRAMMING ASSINGMENT PAGE 55,80 COMMENT | PROGRAM PROGRAMMER DATE CLASS INSTRUCTOR : : : : : 8-1 PA8-1.ASM KADIR GECKIN 03/12/2000 BSA TECOM DSPLY_STR YAPITASINI KULLANARAK EKRRANA 4 MESAJ YAZAN PROGRAM INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF 251 ; STACK SEGMENT STACK =================================================== SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DADTA SEGMENT ===================================================== DATA SEGMENT MSG_1 DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB DB MSG_2 MSG_3 MSG_4 DATA PARA PUBLIC 'DATA' 13,10,10,10,10,10 'Once there was assembly-language' 'student...',13,10,10,0 'First, her program wouldn',"'",'t' 'assemble.',13,10 'When it finally assembled, it wouldn' "'",'t link.',13,10 'When it finally linked, it locked up' 'the machine!',13,10,10,0 'She beat her head and wailed and moaned,' 13,10 '"I hate assembly language!' 'Why did I ever take this class?"' 13,10,10,10,10,'^' 'But finally it ran...',13,10,10 'She laped for joy and wooped and' 'But finally it ran...',13,10,10 'She leaed for joy and wooped and ' 'hollered, ',13,10 ' "It work! It works! I',"'", 'm ' 'so glad took this class!"' 13,10,10,10,0 ENDS ;CODE SEGMENT ========================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX,0 AX AX,DATA DS,AX DS:DATA DSPLY_STR <OFFSET MSG_1> MOV AX,OFFSET MSG_2 DSPLY_STR AX,0 DSPLY_STR <OFFSET MSG_3> MOV AX,OFFSET MSG_4 MOV BL,0 DSPLY_STR AX,BL RET 252 MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSINGMENT 8-2 PAGE 55,80 COMMENT | PROGRAM PROGRAMMER DATE CLASS INSTRUCTOR : : : : : PA8-2.ASM KADIR GECKIN 03/12/2000 BSA TECOM DSPLY_STRR (SIRALI) YAPITASI KULLANILARAK EKRANA 4 TANE MESAJ YAZAN PROGRAM INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ; STACK SEGMENT =========================================== STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') STACK ENDS ; DATA SEGMENT ================================================ DATA SEGMENT PARA PUBLIC 'DATA' MSG_1 MSG_4 DB DB DB DB DB DB DATA ENDS MSG_2 MSG_3 13,10,'This is a test message.' 13,10,0 'This another message.',13,10,0 'This one uses a caret as a trailer.' 13,10,'^' 10,'This is the end of PA8-2',13,10,0 ; CODE SEGMENT ========================================================= CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH DS MOV PUSH AX,0 AX MOV MOV ASSUME AX,DATA DS,AX DS:DATA 253 DSPLY_STRR <OFFSET MSG_1> MOV DSPLY_STRR DSPLY_STRR AX,OFFSET MSG_2 AX,0 <OFFSET MSG_3> MOV AX,OFFSET MSG_4 MOV BL,0 DSPLY_STRR AX,BL RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSINGMENT 8-3 PAGE 55,80 COMMENT | PROGRAM PROGRAMMER DATE CLASS INSTRUCTOR DSPLY_STRL : : : : : PA8-3.ASM KADIR GEÇKIN 4/12/2000 BSA TECOM CORP. 2000-2001 YAPITASI KULLANILARAK EKRANA 4 MESAJ YAZAN PROGRAM INPUT PARAM'S : NONE OUTPUT PARAM'S: NONE RETURN TO DOS,UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ; STACK SEGMENT ================================================ STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') STACK ENDS ; DATA SEGMENT ================================================= DATA SEGMENT PARA PUBLIC 'DATA' MSG_1 DB M1_END - $ -1 DB 13,10,'This is a test mesage.',13,10 EQU $ DB M2_END -$ -1 DB 'This another message.',13,10 DB M3_END -$ -1 DB 'These strings are stored with a' DB 'lenght byte.',13,10 EQU $ DB M3_END - $ - 1 DB 'These strings are stored with a' DB 'length byte. ',13,10 M1_END MSG_2 M2_END MSG_3 254 M3_END MSG_4 M4_END EQU DB DB EQU DATA ENDS ; CODE $ M4_END -$ -1 10,'This is the end of PA-3',13,10 $ SEGMENT ================================================ CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH DS AX,0 AX MOV MOV ASSUME AX,DATA DS,AX DS:DATA DSPLY_STRL <OFFSET MSG_1> MOV AX,OFFSET MSG_2 DSPLY_STRL AX DSPLY_STRL <OFFSET MSG_3> MOV BX, OFFSET MSG_4 DSPLY_STRL BX RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSINGMENT 8-4 PAGE 55,80 COMMENT | PROGRAM PROGRAMMER DATE CLASS INSTRUCTOR : : : : : PA8-4.ASM KADIR GECKIN 4/12/2000 BSA TECOM CORP. 2000-2001 PRINT_STR YAPITASINI KULLANARAK LPT1 ILE 4 MESAJ BASAN PROGRAM (YAZICIYA) INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS, UPON COMPLETION | IF1 INCLUDE PRINTER.MLB 255 ENDIF ;STACK SEGMENT ============================================== STACK SEGMENT PARA 'STACK' DB 64 DUP ('*STACK*') STACK ENDS ; DATA SEGMENT ============================================== DATA SEGMENT PARA PUBLIC 'DATA' MSG_1 DB DB DB DB DB DB MSG_2 DATA 13,10,'This is a test message.' 13,10,0 'This one uses a caret as a trailer.' 13,10, '^' 10,'This is the end of PA8-4' 13,10,12,0 ENDS ;CODE SEGMENT ============================================= CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC NEAR PUSH MOV PUSH DS AX,0 AX MOV MOV ASSUME AX,DATA DS,AX DS:DATA PRINT_STR <OFFSET MSG_1> MOV AX,OFFSET MSG_2 PRINT_STR AX,0 PRINT_STR <OFFSET MSG_3> MOV AX,OFFSET MSG_4 MOV BL,0 PRINT_STR AX,BL RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 8-5 PAGE 55,80 COMMENT | PROGRAM PROGRAMMER DATE CLASS INSTRUCTOR : : : : : PA8-5.ASM KADIR GE€KIN 05/12/2000 BSA TECOM CORP. 2000-2001 256 PRINT_STRR (SIRALI) YAPITASINI KULLANARAK LPT1 ILE 4 ADET MESAJ BASAN PROGRAM INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS, UPON COMPLETION | IF1 INCLUDE PRINTER.MLB ENDIF ; STACK SEGMENT ================================================== STACK SEGMENT PARA PUBLIC 'STACK' MSG_1 MSG_2 MSG_3 MSG_4 DATA DB DB DB DB DB DB DB 13,10,'This is a text message.' 13,10,0 'Third is another message.',13,10,0 'This one uses a caret as a trailer.' 13,10,'^' 10,'This the end of PA8-5' 13,10,12,0 ENDS ;CODE SEGMENT ====================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME MAIN CD:CODE, SS:STACK PROC FAR PUSH DS MOV PUSH AX,0 AX MOV AX,DATA MOV DS,AX ASSUME DS:DATA PRINT_STRR <OFFSET MSG_1> MOV AX,OFFSET MSG_2 PRINT_STRR <OFFSET MSG_1> MOV AX,OFFSET MSG_2 PRINT_STRR AX,0 PRINT_STRR <OFFSET MSG_3> MOV AX,OFFSET MSG_4 MOV BL,0 PRINT_STRR AX,BL RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSINMENT 8-6 PAGE 55,80 257 COMMENT | PROGRAM PROGRAMMER DATE CLASS INSTRUCTOR : : : : : PA8-6.ASM KADIR GE€KIN 05/12/2000 BSA TECOM CORP. 2000-2001 PRINT_STRL YAPITASINI KULLANARAK LPT1 PROTUYLA 4 ADET MESAJ BASAR INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS,UPON COMPLETION | IF1 INCLUDE PRINTER.MLB ENDIF ; STACK SEGMENT ================================================ STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUB ('*STACK*') ENDS ; DATA SEGMENT ==================================================== DATA SEGMENT PARA PUBLIC 'DATA' MSG_1 DB DB EQU DB DB EQU DB DB DB EQU M1_END - $ -1 13,10, 'This is a test message.',13,10 $ M2_END - $ -1 'This i a test message.',13,10 $ M3_END -$ -1 'These strings are stored with a' 'length byte.',13,10 $ MSG_4 DB DB M4_END - $ -1 10,'This is the end of PA8-6',13,10,0,12 M4_END EQU $ DATA ENDS M1_END MSG_2 M2_END MSG_3 M3_END ;CODE SEGMENT ================================================ CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX,0 AX AX,DATA DS,AX DS:DATA PRINT_STRL <OFFSET MSG_1> 258 MOV AX, OFFSET MSG_2 PRINT_STRL AX PRINT_STRL <OFFSET MSG_3> MOV BX,OFFSET MSG_4 PRINT_STRL BX RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSINMENT 8-7 PAGE 55,80 COMMENT | PROGRAM PROGRAMMER DATE CLASS INSTRUCTOR : : : : : PA8_7.ASM KADIR GECKIN 05/12/2000 BSA TECOM CORP. 2000-2001 BDSPLY_STR YAPITAžI KULLANILARAK EKRANA 4 TANE MESAJ YAZAN PROGRAM INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS, UPON COMLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ; STACK SEGMENT =============================================== STACK SEGMENT PARA PUBLIC 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ; DATA SEGMENT ================================================ DATA SEGMENT PARA PUBLIC 'DATA' MSG_1 MSG_4 DB DB DB DB DB DB DATA ENDS ;CODE SEGMENT ================================================ CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MSG_2 MSG_3 13,10,'This is a test message.' 13,10,0 'This is another message.',13,10,0 'This one uses a caret as a trailer.' 13,10,'^' 10,'This is the end of PA8-7',13,10,0 259 MAIN PROC FAR PUSH DS MOV PUSH AX,0 AX MOV AX,DATA MOV DS,AX ASSUME DS:DATA BDSPLY_STR <OFFSET MSG_1> MOV AX,OFFSET MSG_2 BDSPLY_STR AX,0,07H,0 BDSPLY_STR <OFFSET MSG_3> MOV AX,OFFSET MSG_4 MOV BX,0 BDSPLY_STR AX,BL,R,BH RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSINGMENT 8-8 PAGE 55,80 COMMENT | PROGRAM PROGRAMMER DATE CLASS INSTRUCTOR : : : : : PA8-8.ASM KADIR GE€KIN 05/12/2000 BSA TECOM CORP. 2000-2001 BDSPLY_STR YAPITASINI KULLANARAK EKRANA OZELLILERI ILE BIRLIKTE 4 MESAJ YAZAN PROGRAM INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ;STACK SEGMENT ================================================== DATA SEGMENT PARA STACK 'STACK' MSG_1 DB DB DB DB DB DB MSG_2 MSG_3 MSG_4 13,10,'This is a test message.' 13,10,0 'This is another message.',13,10,0 'This one uses a caret as a trailer.' 13,10,'^' 10,'This is the end of PA8_8',13,10,0 260 DATA ENDS ;CODE SEGMENT =========================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME MAIN CS:CODE, SS:STACK PROC FAR PUSH DS MOV AX,0 PUSH AX MOV MOV ASSUME AX,DATA DS,AX DS:DATA BDSPLY_STR <OFFSET MSG_1>, , , 1 MOV AX,OFFSET MSG_2 BDSPLY_STR AX,0,07H,1 BDSPLY_STR <OFFSET MSG_3>,'^',B,1 MOV AX,OFFSET MSG_4 MOV BL,0 MOV BH,1 BDSPLY_STR AX,BL,R,BH SELECT_PAGE 1 CALL PAUSE SELECT_PAGE 0 RET MAIN ENDP ;----------------------------------------------------------------; PROOCEDURE TO PAUSE A FEW SECONDS PAUSE PROC NEAR PUSH MOV CX CX,75 LOOP_1: PUSH CX MOV CX,0 LOOP_2: LOOP POP LOOP POP LOOP POP RET PAUSE CODE ENDP ENDS END MAIN LOOP_2 CX LOOP_1 CX LOOP_1 CX 261 TITLE PAGE COMMENT | PROGRAMMING ASSSIGMENT 55,80 PROGRAM PROGRAMMER DATE CLASS INSTRUCTOR : : : : : PA8-9.ASM KADIR GECKIN 05/12/2000 BSA 98220213 TECOM CORP. 2000-2001 BPRINT_STR YAPITASINI KULLANARAK LPT1 PORTU ILE (OLAN HERHANGI BIR YAZICIYA) 4 TANE MESAJ BASAR INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS,UPON COMPLETION | IF1 INCLUDE PRINTER.MLB ENDIF ; STACK SEGMENT ======================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT =========================================================== DATA SEGMENT PARA PUBLIC 'DATA' MSG_1 DB DB DB DB DB DB DATA ENDS 13,10,'This is another message.',13,10,0 13,10,0 'This another message.',13,10,0 13, 10, '^' 10,'This the end of PA8-9' 13,10,12,0 ;CODE SEGMENT ========================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME MAIN CS:CODE, SS:STACK PROC FAR PUSH DS MOV PUSH MOV MOV ASSUME BPRINT AX,0 AX AX,DATA DS,AX DS:DATA <OFFSET MSG_1> 262 MOV AX,OFFSET MSG_2 BPRINT_STR AX,0,PRN BPRINT_STR <OFFSET MSG_3>,'^',LPT1 MOV MOV BPRINT_STR AX,OFFSET MSG_4 BX,0 AX,BL,BX RET MAIN ENDP CODE ENDS END MAIN TITLE PROGRAMMING ASSINGMENT 8-10 PAGE 55,80 COMMENT | PROGRAM PROGRAMMER DATE CLASS INSTRUCTOR : : : : : PA8-10.ASM KADIR GE€KIN 05/12/2000 BSA - 9822013 TECOM CORP. 2000-2001 BPRINT_STRR YAPITASINI KULLANARAK LPT1 PORTU ILE (OLAN HERHANGI BIR YAZICIYA) 4 TANE MESAJ BASAR INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS,UPON COMPLETION | IF1 INCLUDE PRINTER.MLB ENDIF ;STACK SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' DB STACK ;DATA 80 DUP ('*STACK*') ENDS SEGMENT ================================================== DATA SEGMENT PARA PUBLIC 'DATA' MSG_1 DB DB DB DB DB DB DB MSG_2 MSG_4 DATA 13,10,'This is a test message.' 13,10,0 'This another message.',13,10,0 'This one uses a caret as a trailer.' 13,10,'^' 10,'This is the end of PA8-10' 13,10,12,0 ENDS 263 ; CODE SEGMENT ================================================= CODE SEGMENT PARA PUBLIC 'CODE' ASSUME MAIN CS:CODE, SS:STACK PROC FAR PUSH DS MOV AX,DATA MOV DS,AX ASSUME DS:DATA BPRINT_STRR <OFFSET MSG_1> MOV AX,OFFSET MSG_2 BPRINT_STRR AX,0,PRN BPRINT_STRR <OFFSET MSG_3> MOV AX,OFFSET MSG_4 MOV BX,0 BPRINT_STRR AX,BL,BX RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSINMENT 8-11 PAGE 55,80 COMMENT | PROGRAM PROGRAMMER DATE CLASS INSTRUCTOR : : : : : PA8-11.ASM KADIR GE€KIN 06/12/2000 BSA TECOM CORP. 2000-2001 BPRINT_STRL YAPITASINI KULLANARAK LPT1 ˜LE (HERHANGI BIR YAZICIYA) 4 TANE MESAJ BASAR MESAJLAR BIRER BYTE OLARAK SAKLANIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS,UPON COMPLETION | IF1 INCLUDE PRINTER.MLB ENDIF ; STACK SEGMENT =================================================== STACK SEGMENT PARA STACK 'STACK' 264 DB STACK 64 DUP ('*STACK*') ENDS ; DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' MSG_1 DB DB EQU DB DB DB EQU DB DB EQU ENDS M1_END MSG_3 M3_END MSG_4 M4_END DATA M1_END -$ - 1 13,10,'This is a test message.',13,10 $ M2_END -$ - 1 'These string are stored with a' 'lenght byte.',13,10 $ M4_END - $ - 1 10,',This is the end of PA8-11',13,10,12 $ ;CODE SEGMENT ======================================================= CODE SEGMENT PARA PUBLIC 'CODE' ASSUME MAIN CS:CODE, SS:STACK PROC FAR PUSH DS MOV PUSH AX,0 AX MOV MOV ASSUME AX,DATA DS,AX DS:DATA BPRINT_STRL <OFFSET MSG_1> MOV AX,OFFSET MSG_2 BRINT_STRL AX,PRN BRINT_STRL <OFFSET MSG_3> MOV AX,OFFSET MSG_4 MOV BX,0 BPRINT_STRL AX,BX RET MAIN ENDP CODE ENDS END MAIN TITLE PROGRAMMING ASSINMENT 265 8-12 PAGE COMMENT | 55,80 PROGRAM PROGRAMMER DATE CLASS INSTRUCTOR : : : : : PA8-12.ASM KADIR GECKIN 06/12/2000 BSA TECOM CORP. 2000-2001 SET_VID_MODE, WRITE_PIXEL DSPLY_STR YAPITASINI KULLANARAK GRAFIK KIPINDE (06H = 640/200) KUTU CIZEN VE ICINE BAZI YAZILAR YAZAN PROGRAM INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ; STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT ==================================================== DATA SEGMENT PARA PUBLIC 'DATA' MSG_1 MSG_2 MSG_3 DB DB DB DATA ENDS 'This is a test message.',13,10,0 'This is another message.',13,10,0 'This is the end of PA8-12',13,10,0 ;CODE SEGMENT ============================================ CODE SEGMENT PARA PUBLIC 'CODE' ASSUME MAIN CS:CODE, SS:STACK PROC FAR PUSH MOV PUSH DS AX,0 AX MOV AX,DATA MOV DS,AX ASSUME DS:DATA LP1: SET_VID_MODE 06H MOV AX,40 MOV CX,599 - 40 + 1 WRITE_PIXEL 20,AX,1 WRITE_PIXEL 179,AX,1 INC AX LOOP LP1 MOV AX,20 MOV CX,179 - 20 + 1 266 LP2: LOOP WRITE_PIXEL WRITE_PIXEL INC AX LP2 AX,40,1 AX,599,1 $LOCATE 7, 27 DSPLY_STR <OFFSET MSG_1> $LOCATE 12, 27 DSPLY_STR <OFFSET MSG_2> $LOCATE 17, 26 DSPLY_STR <OFFSET MSG_3> CALL PAUSE SET_VID_MODE 03H RET MAIN ENDP ; ---------------------------------------------------------------------; PROCEDURE TO PAUSE A FEW SECONDS PAUSE PROC NEAR PUSH CX MOV CX,75 LOOP_1: PUSH MOV CX CX,0 LOOP_2: LOOP POP LOOP POP RET LOOP_2 CX LOOP_1 CX PAUSE CODE ENDP ENDS END MAIN 267 ASSEMBLY PROGRAM ÖRNEKLERİ BOLUM-4: COMMENT | INPUT_CHR MACRO ============================================ CONSOLE.LIB ICINDE $INPUT_CHR PROSEDURU ILE DOS ALTINDA KLAVYEDEN BIR KARAKTER GIRER INPUT PARAMETERS: NONE OUTPUT PARAMETERS: CHAR = CHARACTER TYPED ON KEYBOARD BYTE, REGISTER OPTIONAL - MAY BE OMITTED FOR KBRD STALL CARRY FLAG SET IF EXTENDED-KEYBOARD CHARACER, CLEAR IF NORMAL ASCII PROPERLY RETURN <CTRL>+<@> (<CTRL>+<2>) AS ASCII NUL CHARACTER (0) | INPUT_CHR MACRO CHAR IFNDEF $INPUT_CHR EXTRN $INPUT_CHR:NEAR ENDIF PUSH DEC BP SP MOV CALL BP,SP $INPUT_CHR IFNB <CHAR> MOV CHAR, BYTE PTR [BP] ENDIF INC SP POP BP ENDM COMMENT | BINPUT_CHR MACRO ============================================ CONSOLE.LIB'IN ICINDE $INPUT_CHR PROSEDUR ILE BIOS ALTINDA KLAVYEDEN TEKBIR KARAKTER EKLER INPUT PARAMETERS : NONE OUTPUT PARAMETERS : CHAR = CHARACTER TYPED ON KEYBOARD BYTE, REGISTER OPTIONAL - MAY BE OMITED FOR KBRD STALL SCAN = SCANB CODE OF ASCII CHARACTER BYTE, REG˜STER OPTIONAL - MAY BE OMITED FOR KBRD STALL CARRY FLAG SET IF EXTENDED - KEYBOARD CHARACTER BYTE, REGISTER OPTIONAL - MAY MAY BE OMITED GOR KBRD STALL 268 CARRY FLAG SET IF EXTENDED-KEYBOARD CHARACTER, CLEAR IF NORMAL ASCII PROPERLY RETURNS <CTRL>+<@> (<CTRL>+<2>) AS ASCII NUL CHARACTER (0) | BINPUT_CHR MACRO CHAR,SCAN IFNDEF $BINPUT_CHR EXTRN $BINPUT_CHR:NEAR ENDIF PUSH BP DEC SP DEC SP MOV BP,SP CALL $BINPUT_CHR IFNB <CHAR> MOV CHAR,BYTE PTR [BP] ENDIF IFNB <SCAN> MOV SCAN,BYTE PTR [BP+1] ENDIF INC INC POP SP SP BP ENDM COMMENT | CHECK_KBRD MACRO ======================================== CONSOLE.LIB ICINDE $CHECK_KBRD PROSEDURU ILE KARAKTER HAZIR ISE KLAVYE DURUMUNU GORUR, DENETLER INPUT PARAMETERS : NONE OUTPUT PARAMETERS : STATUS = KEYBOARD STATUS BYTE,REGISTER 00H = NO CHARACTER READY FFH = AT LEAST 1 CHARACTER READY | CHECK_KBRD MACRO STATUS IFNDEF $CHECK_KBRD EXTRN $CHECK_KBRD:NEAR ENDIF PUSH DEC MOV CALL MOV INC POP BP SP BP,SP $CHECK_KBRD STATUS, BYTE PTR [BP] SP BP ENDM COMMENT | CHECK_KEY SUB-PROSEDUR IN CONSOLE.LIB 269 INPUT PARAMETERS : NONE OUTPUT PARAMETERS : KEY STATUS SIZE : BYTE ADDRESSING MODES: REGISTER ONLY BIT 0 1 2 3 4 5 6 7 # KEY <RIGHT SHIFT> <LEFT SHIFT> <CTRL> <ALT> <SCROLL LOCK> <NUM LOCK> <CAPS LOCK> <INS> MEANING 1 = DEPRESSED 1 = DEPRESSED 1 = DEPRESSED 1 = DEPRESSED 1 = TOGLE ON 1 = TOGLE ON 1 = TOGLE ON 1= TOGLE ON | CHECK_KEY MACRO KEYS IFNDEF $CHECK_KEYS EXTRN $CHECK_KEYS:NEAR ENDIF PUSH DEC BP SP MOV BP,SP CALL $CHECK_KEYS MOV INC POP KEYS,[BP+0] SP BP ENDM COMMENT | FLUSH_KBRD MACRO ========================================= CONSOLE.LIB ICINDE $FLUSH_KBRD PROSEDURU ILE KLAVYE TAMPONUNU TEMIZLER (TIP ILERISINI DISLAR) INPUT PARAMETERS : NONE OUTPUT PARAMETERS : NONE | FLUSH_KBRD MACRO IFNDEF $FLUSH_KBRD EXTRN $FLUSH_KBRD:NEAR ENDIF CALL $FLUSH_KBRD ENDM COMMENT | DSPLY_IMMED_STR MACRO =================================== DSPLY_STR MACROYU KULLANARAK KES˜N STRINGI G™STER˜R YARDIM ˜€˜N BAžVURUYOR ** DATA ˜S˜ML˜ PAR€AYI ˜€ERMEL˜D˜R. ™RNE¦˜N : DATA SEGMENT Align combine 'class' INPUT PARAMETERS : STRING = STRING TO DSIPLAY IMMEDIATE VALUE,CHARACTER IN 270 QUOTES AND/OR BYTE VALUES ENCLOSED IN ANGLE BRACKETS TRAILER = CHARACTER TO BE USED AS TRAILER TO MARK END OF STRING SIZE : BYTE ADRESSING MODES : REGISTER OR IMMEDIATE DEFAULT =NUL OUTPUT PARAMETERS: NONE NO REGISTERS MODIFIED | DSPLY_IMMED_STR MACRO STRING, TRAILER LOCAL STR_BFR DATA SEGMENT STR_BFR DB STRING IFB <TRAILER> DB 0 ELSE DB TRAILER ENDIF DATA ENDS DSPLY_STR <OFFSET STR_BFR>,<TRAILER> ENDM COMMENT | BDSPLY_IMMED_STR MACRO =============================== DSPLY_STR MACROYU KULLANARAK KES˜N STRINGI GOSTEROR YARDIM ˜€˜N BASVURUYOR ** DATA ADLI PARCAYI DATA SEGMENT Align combine 'class' INPUT PARAMETERS : STRING = STRING TO DSIPLAY IMMEDIATE VALUE,CHARACTER IN QUOTES AND/OR BYTE VALUES ENCLOSED IN ANGLE BRACKETS TRAILER = CHARACTER TO BE USED AS TRAILER TO MARK END OF STRING SIZE : BYTE ADRESSING MODES : REGISTER OR IMMEDIATE DEFAULT =NUL ATT = ATTRIBUTE FOR DISPLAY SIZE : BYTE ADRESSING MODES : REGISTER OR IMMEDIATE DEFAULT : NORMAL VIDEO (07H) N = NORMAL (07H) R = REVERSE (70H) B = BLINK (87H) - MONOCHROME ONLY H = HIGHLIGHT (OFH) OTHER = BINARY ATTRIBUTE PAGE = PAGE TO DISPLAY TO SIZE : BYTE ADRESSING MODES: REGISTER OT IMMEDIATE DEFAULT : 0 OUTPUT PARAMETERS : NONE NO REGISTERS MODIFIED | 271 BDSPLY_IMMED_STR MACRO LOCAL DATA STRING, TRAILER,ATT,PAGE STR_BFR SEGMENT STR_BFR DB STRING IFB <TRAILER> DB 0 ELSE DB TRAILER ENDIF DATA ENDS BDSPLY_STR <OFFSET STR_BFR>,<TRAILER>,<ATT>,PAGE ENDM COMMENT | INPUT_STR MACRO ====================================== CONSOLE.LIB ICINDE $INPUT_STR PROSEDURU ILE DATA SEGMENTIN ICINDE TAMPONDA SAKLI OLARAK KLAVYEDEN BIR STRING GIRER STRING KUYRYKTA SAKLANIR INPUT PARAMETERS: BUFF_OFF = OFFSET OF BUFFERTO HOLD STRING WORD, REGISTER OR IMMEDIATE MAX_LEN = # OF CHARACTER TO ALLOW BYTE, REGISTER OR IMMEDIATE DEFAULT = 80 BUFFER LENGTH MUST BE AT LEAST 1 MORE THAN MAX_LEN TRAILER = CHARACTER TO USE TO MARK END OF STRING BYTE, REGISTER OR IMMEDIATE DEFAULT = NUL(0) OUTPUT PARAMETERS: NONE | INPUT_STR MACRO BUFF_OFF, MAX_LEN, TRAILER IFNDEF $INPUT_STR EXTRN $INPUT_STR:NEAR ENDIF PUSH SUB MOV MOV BP SP,4 BP,SP WORD PTR [BP], BUFF_OFF IF <MAX_LEN> MOV BYTE PTR ELSE MOV BYTE PTR ENDIF IFB <TRAILER> MOV BYTE PTR ELSE MOV BYTE PTR ENDIF CALL $INPUT_STR [BP+2],80 [BP+2], MAX_LEN [BP+3],0 [BP+3],TRAILER 272 POP BP ENDM COMMENT | INPUT_STR MACRO =================================== CONSOLE.LIB ˜€˜NDE $INPUT_STR PROSEDURU ˜LE DATA SEGMENTTE TAMPONLA SAKLI OLARAK KLAVYEDEN BIR STRING GIRER STRING KUYTUKLA SAKLANIR INPUT PARAMETERS: BUFF_OFF = OFFSET OF BUFFER TO HOLD STRING WORD REGISTER OR IMMEDIATE MAX_LEN = # OF CHARACTERS TO ALLOW BYTE, REGISTER OR IMMEDIATE DEFAULT = 80 BUFFER LENGTH MUST BE AT LEAST 1 MORE THAN MAX_LEN TRAILER = CHARACTER TO USE TO MARK END OF STRING BYTE, REGISTER OR IMMEDIATE DEFAULT =NUL (0) OUTPUT PARAMETERS: NONE | INPUT_STR MACRO BUFF_OFF, MAX_LEN, TAILER IFNDEF $INPUT_STR EXTRN $INPUT_STR:NEAR ENDIF PUSH SUB BP SP,4 MOV MOV BP,SP WORD PTR [BP],BUFF_OFF IFB <MAX_LEN> MOV BYTE PTR [BP+2],80 ELSE MOV BYTE PTR [BP+2],MAX_LEN ENDIF IFB <TRAILER> MOV BYTE PTR [BP+3],0 ELSE MOV BYTE PTR [BP+3],TRAILER ENDIF CALL $INPUT_STR POP BP ENDM COMMENT | INPUT_STRL MACRO ===================================== CONSOLE.LIB ICINDE $INPUT_STRL PROSEDURU ILE DATA SEGMENTTE TAMPONLA SAKLI OLARAK KLAVYEDEN BIR STRING GIRER STRING BIR BYTE OLARAK SAKLANIR INPUT PARAMETERS: BUFF_OFF = OFFSET OF BUFFER TO HOLD STRING WORD, REGISTER OR IMMEDIATE MAX_LEN = # OF CHARACTERS TO ALLOW BYTE,REGISTER OR IMMEDIATE 273 DEFAULT = 80 BUFFER LENGTH MUST BE AT LEAST 1 MORE THAN MAX_LEN OUTPUT PARAMETERS: NONE | INPUT_STRL MACRO BUFF_OFF,MAX_LEN IFNDEF $INPUT_STRL: NEAR ENDIF PUSH MOV BP SP,3 MOV MOV BP,SP WORD PTR [BP],BUFF_OFF IFB <MAX_LEN> MOV BYTE PTR [BP+2],80 ELSE MOV BYTE PTR [BP+2],MAX_LEN ENDIF IFB <TRAILER> MOV BYTE PTR [BP+3],0 ELSE MOV BYTE PTR [BP+3],TRAILER ENDIF IFB <ECHO_ATT> MOV BYTE PTR [BP+4],07H ELSE IFIDN <ECHO_ATT>,<N> MOV BYTE PTR [BP+4],07H ELSE IFIDN <ECHO_ATT>,<R> MOV BYTE PTR [BP+4],70H ELSE IFIDN <ECHO_ATT>,<B> MOV BYTE PTR [BP+4],87H ELSE IFIDN <ECHO_ATT>,<H> MOV BYTE PTR [BP+4],0FH ELSE MOV BYTE PTR [BP+4], ECHO_ATT ENDIF ENDIF ENDIF ENDIF ENDIF IFB <ECHO_PAGE> MOV BYTE PTR [BP+5],0 ELSE MOV BYTE PTR [BP+5], ECHO_PAGE ENDIF CALL $BINPUT_STR POP BP ENDM COMMENT | BINPUT_STRL MACRO ================================== 274 CONSOLE.LIB ICINDE $BINPUT_STRL PROSEDURU ILE DATA SEGMENT TAMPONUNDA SAKLI OLARAK KLAVYEDEN BIR STRING GIRER HER SAYFAYA BELIRTILEN OZELLIKLE BASAR STRING BIR BYTE ILE SAKLANIR INPUT PARAMETERS: BUFF_OFF = OFFSET OF BUFFER TO HOLD STRING WORD, REGISTER OR IMMEDIATE MAX_LEN = # OF CHARACTERS TO ALLOW BYTE, REGISTER OR IMMEDIATE DEFAULT = 80 BUFFER LENGTH MUST BE AT LEAST 1 MORE THAN MAX_LEN ECHO_ATT = ATTIRBUTE FOR ECHO SIZE: BYTE ADRESSING MODES: REGISTER OR IMMEDIATE DEFAULT : NORMAL VIDEO (07H) N = NORMAL (07H) R = REVERSE (07H) B = BLINK (87H) - MONOCHROME ONLY H = HIGHLIGHT (OFH) OTHER = BINARY ATTRIBUTE ECHO_PAGE = PAGE TO ECHO TO SIZE: BYTE ADDRESSING MODES: REGISTER OR IMMEDIATE DEFAULT: 0 OUTPUT PARAMETERS: NONE | BINPUT_STRL MACRO BUFF_OFF, MAX_LEN, ECHO_ATT, ECHO_PAGE IFNDEF $BINPUT_STRL EXTRN $BINPUT_STRL:NEAR ENDIF PUSH SUB BP SP,5 MOV MOV BP,SP WORD PTR [BP], BUFF_OFF IFB <MAX_LEN> MOV BYTE PTR [BP+2],80 ELSE MOV BYTE PTR [BP+2],MAX_LEN ENDIF IFB <ECHO_ATT> MOV BYTE PTR [BP+3],07H ELSE IFIDN <ECHO_ATT>,<N> MOV BYTE PTR [BP+3],07H ELSE IFIDN <ECHO_ATT>,<R> MOV BYTE PTR [BP+3],87H ELSE IFIDN <ECHO_ATT>,<H> MOV BYTE PTR [BP+3],0FH ELSE 275 MOV BYTE PTR [BP+3],ECHO_ATT ENDIF ENDIF ENDIF ENDIF ENDIF IFB <ECHO_PAGE> MOV BYTE PTR [BP+4],0 ELSE MOV BYTE PTR [BP+4],ECHO_PAGE ENDIF CALL $BINPUT_STRL POP BP ENDM COMMENT | $BINP_CH.ASM KADIR GECKIN BIOS KLAVYE HIZMETI (INT 16H), ISLEM 00H KULLANILARAK TARAMA KIPINDE KLAVYEDEN B˜R KARAKTER OKUYAN ALTYORDAM EGER UZATILMIS KLAVYE KARAKTERLERI HAZIR BIR SEKILDE <CTRL>+<@> VE ASCII NUL KARAKTER (0) ˜LE DONUYORSA CARRY BAYRAGINI AYARLAR INPUT PARAMETERS : NONE OUTPUT PARAMETERS : KEYBOARD CHARACTER SIZE: BYTE LOCATION: [BP+0] SCAN CODE OF ASCII CHARACTER SIZE: BYTE LOCATION: [BP+1] CARRY SET IF EXTENDED-KEYBOARD CHAR, CLEARED IF ASCII | TITLE PAGE DATA $BINP_CH.ASM 55,80 SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT BYTE PUBLIC 'CODE' ASSUME $BINPUT_CHR CS:CODE PROC NEAR PUBLIC $BINPUT_CHR 276 PUSH AX MOV INT CMP JA AH,00H 16H AL,0 ASCII CMP JNE AH,3 EXT_KBRD JMP CLC SHORT DONE ASCII: EXT_KBRD : MOV MOV STC AL, AH AH, 255 DONE: MOV MOV RET [BP+0], AL [BP+1], AH $BINPUT_CHR ENDP CODE ENDS END COMMENT | $BINP_ST.ASM KADIR GECKIN BDSPLY_CHR,BDSPLY_CHR,BDSPLY_IMMED_STR VE BINPUT_CHR YAPITASLARI KULLANILARAK DATA SEGMENTTE BIR TAMPONDA SAKLI BIR STRING GIREN PROSEDUR INPUT PARAMETERS: OFFSET OF BUFFER TO RECEIVE STRING SIZE: WORD LOCATION: [BP+0] MAXIMUM NUMBER OF CHARACTER TO ALLOW SIZE: BYTE LOCATION: [BP+2] TRAILER TO USE ON STRING SIZE: BYTE LOCATION: [BP+4] PAGE FOR ECHO SIZE: BYTE LOCATION: [BP+5] OUTPUT PARAMETERS: NONE ALL REGISTERS RESTORED | TITLE PAGE $BINP_ST.ASM 55,80 INCLUDE CONSOLE.MLB DATA SEGMENT WORD PUBLIC 'DATA' 277 ASSUME DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME $BINPUT_STR BEEP: CHR_LOOP: CS:CODE PROC NEAR PUBLIC $BINPUT_STR PUSH PUSH PUSH MOV AX BX SI SI,[BP+0] MOV MOV BH,[BP+4] BL,[BP+5] MOV JMP AH,0 SHORT CHR_LOOP BDSPLY_CHR BINPUT_CHR JC BEEP CMP JE CMP JNE CMP JE AL,13 DONE AL,8 NO_BS AH,0 BEEP 7 AL BDSPLY_IMMED_STR NO_BS: DEC DEC JMP CMP JAE <8,32,8>, , , BL SI AH CHR_LOOP AH,[BP+2] BEEP MOV [SI],AL INC SI INC AH BDSPLY_CHR AL,BH,BL JMP DONE: $BINPUT_STR CODE CHR_LOOP MOV AL,[BP+3] MOV [SI],AL BDSPLY_IMMED_STR POP POP POP SI BX AX RET 6 ENDP ENDS 278 END COMMENT | $BINP_SL.ASM KADIR GECKIN BDSPLY_CHR, BDSPLY_IMMED_STR VE BINPUT_CHR YAPITASLARIYLA DATA SEGMENTIN TAMPONUNDA SAKLI BIR DTYRING GIREN PROSEDUR STRING BIR BYTE OLARAK SAKLANIR INPUT PARAMETERS: OFFSET OF BUFFER TO RECEIVE STRING SIZE: WORD LOCATION: [BP+0] MAXIMUM NUMBER OF CHARACTERS TO ALLOW SIZE: BYTE LOCATION: [BP+3] PAGE FOR ECHO SIZE: BYTE LOCATION: [BP+3] PAGE FOR ECHO SIZE: BYTE LOCATION: [BP+4] OUTPUT PARAMETERS: NONE ALL REGISTERS RESTORED | TITLE $BINP_SL.ASM PAGE 55,80 INCLUDE CONSOLE.MLB DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $BINPUT_STRL PROC PUBLIC NEAR $BINPUT_STRL PUSH AX PUSH PUSH MOV BX SI SI,[BP+0] INC MOV MOV SI BH,[BP+3] BL,[BH+4] MOV AH,0 279 JMP SHORT CHR_LOOP BDSPLY_CHR 7 BINPUT_CHR AL BEEP: CHR_LOOP: JC CMP JE CMP JNE CMP JE BEEP AL,13 DONE AL,8 NO_BS AH,0 BEEP BDSPLY_IMMED_STR <8,32,8>, , , BL DEC DEC JMP CMP JAE NO_BS: SI AH CHR_LOOP AH,[BP+2] BEEP MOV [SI],AL INC AH BDSPLY_CHR AL,BH,BL JMP DONE: CHR_LOOP MOV SI,[BP+0] MOV [SI],AH BDSPLY_IMMED_STR $BINPUT_STRL CODE COMMENT | POP POP POP SI BX AX RET 5 ENDP ENDS END $CHK_KBD.ASM KAD˜R GE€K˜N DOSUN 0BH FONKS˜YONU KULLANILARAK KLAVYE TAMPONUNUN GUNCEL DURMUNU DENETLEYEN ALTYORDAM HICBIR KARAKTERT HAZIR DEGILSE DONER, FFH DEGERI YOLLANIR INPUT PARAMETERS: NONE OUTPUT PAREAMETERS: NONE KEYBOARD STATUS SIZE : BYTE LOCATION : [BP+0] | TITLE $CHK_KBD.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA 280 DATA ENDS CODE SEGMENT BYTE PUBLIC 'CODE' ASSUME $CHECK_KBRD CS:CODE PROC NEAR PUBLIC $CHECK_KBRD PUSH AX MOV INT AH,0BH 21H MOV POP RET [BP+0],AL AX $CHECK_KBRD ENDP CODE ENDS END COMMENT | $CHK_KYS.ASM KADIR GECKIN 16H KESMESI ILE (BIOS KLAVYE HIZMETI), ISLEM 02H SHIFT VE TOGGLE DUGMELERININ GUNCEL DURUMLARINI DENETLEYEN ALTYORDAM INPUT PARAMETERS: NONE OUTPUT PARAMETERS : SHIFT AND TOGGLE KEYS STATUS BYTE SIZE: BYTE LOCATION: [BP+0] | TITLE $CHK_KYS.ASM PAGE 55,80 DATA SEGMENT BYTE PUBLIC 'CODE' ASSUME $CHECK_KEYS CODE $CHECK_KEYS PUSH AX MOV INT AH,02H 16H MOV POP RET [BP+0],AL AX ENDP ENDS END 281 COMMENT | $FLSH_KB.ASM KADIR GECKIN DOSUN OCH FOKSIYONU KULLANILARAK KLAVYE TAMPONUNU TEM˜ZLEYEN ALTYORDAM - HER TIPI ELER INPUT PARAMETERS:NONE OUTPUT PARAMETERS: NONE | TITLE PAGE DATA $FLUSH_KB.ASM 55,80 SEGMENT WORD PUBLIC 'CODE' ASSUME DS:DATA DATA ENDS CODE SEGMENT BYTE PUBLIC 'CODE' ASSUME $FLUSH_KBRD CS:CODE PROC NEAR PUBLIC $FLUSH_KBRD $FLUSH_KBRD CODE PUSH AX MOV MOV INT POP RET AH,0CH AL,0 21H AX ENDP ENDS END COMMENT | $INP_STR.ASM KADIR GECKIN DSPLY_CHR, DSPLY_IMMED_STR,AND INPUT_CHR YAPITASLARI KULLANILARAK DATA SEGMENTTTE SAKLI BIR STRING GIRER, STRING KUYRUKTADIR INPUT PARAMETERS: OFFSET OF BUFFER TO RECEIVE STRING SIZE: WORD LOCATION: [BP+0] MAXIMUM NUMBER OF CHARACTER TO ALLOW 282 SIZE:BYTE LOCATION:[BP+2] TRAILER TO USE ON STRING SIZE: BYTE LOCATION:[BP+3] OUTPUT PARAMETERS: NONE ALL REGISTERS RESTORED | TITLE $INP_STR.ASM PAGE 55,80 INCLUDE DATA CONSOLE.MLB SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $INPUT_STR PROC NEAR PUBLIC $INPUT_STR BEEP: CHR_LOOP: PUSH PUSH AX SI MOV SI,[BP] MOV AH,0 JMP SHORT CHR_LOOP DSPLY_CHR INPUT_CHR JC BEEP CMP JE CMP JNE CMP JE 7 AL AL,13 DONE AL,8 NO_BS AH,0 BEEP DSPLY_IMMED_STR NO_BS: DEC DEC JMP CMP JNB <8,32,8> SI AH CHR_LOOP AH,[BP+2] BEEP MOV [SI],AL INC SI INC AH DSPLY_CHR AL JMP CHR_LOOP 283 DONE: MOV AL,[BP+3] MOV [SI],AL DSPLY_IMMED_STR $INPUT_STR CODE POP POP SI AX RET 4 <13,10> ENDP ENDS END TITLE PROGRAMMING ADSSINGMENT 9-1 PAGE 55,80 COMMENT | PROGRAM: PA9-1 PROGRAMMER: KADIR GECKIN DATE: 11/12/2000 INPUT_CHR,DSPLY_CHR VE DSPLY_IMMED_STR YAPITASI ILE KARAKTER GIREN VE EKRANDA GOSTEREN PROGRAM INPUT PARAM'S: NONE OUTPUT PARTAM'S: NONE RETURN TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ;STACK SEGMENT ================================================= STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT ============================================================ DATA SEGMENT PARA STACK 'DATA' DATA ENDS ;CODE CODE SEGMENT ================================================= SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC NEAR PUSH DS MOV AX,0 PUSH AX MOV AX,DATA 284 MOV ASSUME BEG_LP: END_LP: DS,AX DS:DATA DSPLY_IMMED_STR 'Press any extended key to stop' DSPLY_IMMED_STR <13,10> INPUT_CHR CL JC END_LP DSPLY_CHR CL JMP BEG_LP DSPLY_IMMED_STR <13,10,'Press any key to return'> DSPLY_IMMED_STR <'to DOS',13,10> INPUT_CHR RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSINMENT 9-2 PAGE 55,80 COMMENT | PROGRAM: PA9-2.ASM PROGRAMMER: KADIR GECKIN DATE: 11/12/2000 BINPUT_CHR,DSPLY_CHR VE DSPLY_IMMED_STR YAPITASLARI ILE (KARAKTERIN KAYNAGINI GOSTEREREK) KARAKTERLER GIRER VE GOSTERIR. INPUT PARAM'S:NONE OUTPUT PARAM'S: NONE RETURN TO DOS,UPON CONPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ;STACK SEGMENT ================================================ STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT ================================================= DATA SEGMENT PARA PUBLIC 'DATA' DATA ENDS ;CODE SEGMENT ================================================ CODE SEGMENT PARA PUBLIC 'CODE' 285 ASSUME MAIN CS:CODE, SS:STACK PROC FAR PUSH DS MOV PUSH AX,0 AX MOV AX,DATA MOV DS,AX ASSUME DS:DATA DSPLY_IMMED_STR DSPLY_IMMED_STR BEG_LP: JC NOT_ZERO: KEYPAD: END_LP: 'Press any extended key to stop' <13,10> BINPUT_CHR BH,BL END_LP DSPLY_CHR BH CMP BL,0 JNE NOT_ZERO DSPLY_IMMED_STR '(<alt>+numeric keypad)' JMP BEG_LP CMP BL,59 JAE KEYPAD DSPLY_IMMED_STR '(Main keyboard)' JMP BEG_LP DSPLY_IMMED_STR '(Numeric keypad)' JMP BEG_LP DSPLY_IMMED_STR<13,10,'Press any key to return'> DSPLY_IMMED_STR <'to DOS',13,10> BINPUT_CHR RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSINGMENT 9-3 PAGE 55,80 COMMENT | PROGRAM : PA9-3.ASM PROGRAMMER : KADIR GECKIN DATE : 12/12/2000 CHECK_KBRD,DSPLY_IMMED_STR VE INPUT_CHR YAPITASLARI KULLANILARAK KLAVYE DURUMUNU DENETLEYEN, UYGUN KARAKTER OLMADAN YAZMAYA GECMEYEN PROGRAM KARAKTERLERI UZATILMIS KARAKTERLERI GOSTERENE KADAR YINELER INPUT PARAM'S: NONE OUTPUT PARAM'S: NONE RETURN TO DOS,UPON COMPLETION | IF1 286 INCLUDE CONSOLE.MLB ENDIF ;STACK SEGMENT ==================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT ===================================================== DATA SEGMENT PARA PUBLIC 'DATA' DATA ENDS ;CODE SEGMENT ======================================================= CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH DS MOV PUSH AX,0 AX MOV AX,DATA MOV DS,AX ASSUME DS:DATA DSPLY_IMMED_STR 'Press any extended key to stop' DSPLY_IMMED_STR <13,10> BEG_LP: CHECK_KBD DH CMP DH,0 JNE LP2_END DSPLY_IMMED_STR 'No' JMP BEG_LP LP2_END: INPUT_CHR DH JC LP1_END DSPLY_CHR DH DSPLY_IMMED_STR <13,10> JMP BEG_LP LP1_END: RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSINGMENT 9-4 PAGE 55,80 COMMENT | PROGRAM: PA-9.ASM 287 PROGRAMMER: KADIR GECKIN DATE: 12/12/2000 CHECK_KEYS,DSPLY_IMMED_STR VE INPUT_CHR YAPITASLARI KULLANILARAK SHIFT VE TOGGLE TUSLARININ DURUMUNU DDENETLEYEN PROGRAM INPUT PARAM'S:NONE OUTPUT PARAM'S: NONE RETURN TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ;STACK SEGMENT ================================================= STACK SEGMENT PARA STACK 'STACK' DB STACK ;DATA 64 DUP ('*STACK*') ENDS SEGMENT ================================================= DATA SEGMENT PARA PUBLIC 'DATA' STRT_MSG DB 'Press ve release one or more toggle' DB 'keys,',13,10 DB 'and/or press and hold one or more shift' DB 'then press any other key.',13,10,0 DB 'Up',13,10,0 DB 'Down',13,10,0 DB 'On',13,10,0 DB 'Off',13,10,0 UP_MSG DOWN_MSG ON_MSG OFF_MSG DATA ENDS ;CODE SEGMENT ================================================ CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH DS MOV PUSH AX,0 AX MOV MOV ASSUME AX,DATA DS,AX DS:DATA DSPLY_STR INPUT_CHR CHECK_KEYS TST_RS: <OFFSET STRT_MSG> AL DSPLY_IMMED_STR <13,10,'<Right Shift:'> TEST AL,01H JNZ RS_DN DSPLY_STR <OFFSET UP_MSG> JMP SHORT TST_LS 288 RS_DN: DSPLY_STR TST_LS: DSPLY_IMMED_STR '<Left Shift>:' TEST AL,02H JNZ LS_DN DSPLY_STR <OFFSET UP_MSG> JMP SHORT TEST_LS DSPLY_STR <OFFSET DOWN_MSG> DSPLY_IMMED_STR '<Left shift>:' TEST AL,02H JNZ LS_DN DSPLY_STR <OFFSET DOWN_MSG> DSPLY_IMMED_STR '<Left shift>:' TEST AL,02H JNZ LS_DN DSPLY_STR <OFFSET UP_MSG> JMP SHORT TST_CTL DSPLY_IMMED_STR '<Ctrl>: ' TEST AL,04H JNZ CTL_DN DSPLY_STR <OFFSET UP_MSG> JMP SHORT TST_ALT DSPLY_STR <OFFSET DOWN_MSG> RS_DN: TST_LS: RS_DN: TST_LS: LS_DN: CTL_DN: TST_ALT: ALT_DN: TST_SL: SL_ON: TST_NL: NL_ON: TST_CL: CL_ON: <OFFSET DOWN_MSG> DSPLY_IMMED_STR '<Alt>: ' TEST AL,08H JNZ ALT_DN DSPLY_STR <OFFSET UP_MSG> JMP SHORT TST_SL DSPLY_STR <OFFSET DOWN_MSG> DSPLY_IMMED_STR <13,10,'<Scroll Lock>: ' TEST AL,10H JNZ SL_ON DSPLY_STR <OFFSET OFF_MSG> JMP SHORT TST_NL DSPLY_STR <OFFSET ON_MSG> DSPLY_IMMED_STR '<Num Lock>: ' TEST AL,20H JNZ NL_ON DSPLY_STR <OFFSET OFF_MSG> JMP SHORT TST_CL DSPLY_STR <OFFSET ON_MSG> DSPLY_IMMED_STR '<Caps Lock>: TEST AL,40H JNZ CL_ON DSPLY_STR <OFFSET OFF_MSG> JMP SHORT TST_INS DSPLY_STR <OFFSET ON_MSG> TST_INS: DSPLY_IMMED_STR '<Ins>:' TEST AL,80H JNZ INS_ON DSPLY_STR <OFFSET OFF_MSG> JMP SHORT TST_INS INS_ON: DSPLY_STR <OFFSET ON_MSG> DONE: ; MAIN-LINE CODE ENDS HERE RET MAIN ENDP 289 ' CODE ENDS END MAIN TITLE PROGRAMMING ASSINGMENT 9-5 PAGE 55,80 COMMENT | PROGRAM : PA9-5.ASM PROGRAMMER : KADIR GECKIN DATE : 13/12/2000 FLUSH_KBRD AND INPUT_CHR YAPITASI KULLANILARAK KLAVYE TAMPONUNU TEMIZLER VE BIR KARAKTER GIRER INPUT PARAM'S: NONE OUTPUT PARAM'S: NONE RETURN TO DOS UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ; STACK SEGMENT =============================================== STACK SEGMENT PARA STACK 'STACK' DB STACK ;DATA 64 DUP ('*STACK*') ENDS SEGMENT ================================================ DATA SEGMENT PARA PUBLIC 'DATA' DATA ENDS ;CODE SEGMENT ================================================= CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH DS MOV PUSH AX,0 AX MOV AX,DATA MOV DS,AX ASSUME DS:DATA FLUSH_KBRD INPUT_CHR RET MAIN ENDP 290 CODE ENDS END MAIN TITLE PROGRAMMING ASSIGMENT 9-6 PAGE 55,80 COMMENT | PROGRAM : PA9-6.ASM PROGRAMMER : KADIR GECKIN DATE : 13/12/2000 INPUT_STR,DSPLY_STR VE DSPLY_IMMED_STR YAPITASLARI KULLANILARAK KUYRUKTA SAKLI IKI STRING GIREN PROGRAM INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ;STACK SEGMENT =============================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT ================================================ DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DATA DB 81 DUP('*') ENDS ;CODE CODE SEGMENT =============================================== SEGMENT PARA PUBLIC 'CODE' ASSUME MAIN CS:CODE, SS:STACK PROC FAR PUSH DS MOV PUSH MOV MOV ASSUME AX,0 AX AX,DATA DS,AX DS:DATA INPUT_STR <OFFSET IO_BUF>,10,'#' DSPLY_STR <OFFSET IO_BUF>,'#' 291 DSPLY_IMMED_STR <13,10,10> INPUT_STR <OFFSET IO_BUF> DSPLY_STR <OFFSET IO_BUF> RET MAIN CODE ENDP ENDS END MAIN TITLE PAGE COMMENT | PROGRAMMING ASSINGMENT 9-7 55,80 PROGRAM : PA9-7 PROGRAMMER : KADIR GECKIN DATE : 13/12/2000 INPUT_STRL,DSPLY_STRL VE DSPLY_IMMED_STR YAPITASLARIYLA BYTE UZUNLUKLARIYLA SAKLI IKI STRINGI GIREN VE GOSTEREN PROGRAM INPUT PARAM'S : NONE OUTPUT PARA'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ;STACK SEGMENT ================================================= STACK SEGMENT PARA STACK 'STACK' DB STACK ;DATA 64 DUP ('*STACK*') ENDS SEGMENT ================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DB DATA ENDS 81 DUP('*') ;CODE SEGMENT ==================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH DS MOV PUSH AX,0 AX 292 MOV MOV ASSUME AX,DATA DS,AX DS:DATA INPUT_STRL <OFFSET IO_BUF>,10,'#' DSPLY_STRL <OFFSET IO_BUF>,'#' DSPLY_IMMED_STR <13,10,10> INTPUT_STRL <OFFSET IO_BUF> RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 9-8 PAGE 55,80 COMMENT | PROGRAM : PA9-8.ASM PROGRAMMER : KADIR GECKIN DATE : 13/12/2000 BINPUT_STR, BDSPLY_STR VE BDSPLY_IMMED_STR YAPITASLARI KULLANILARAK BIOS ARACILIGIYLA KUYRUKTA SAKLI IKI STRING GIREN VE GOSTEREN PROGRAM INPUT PARAM'S: NONE OUTPU PARAM'S: NONE RETURN TO DOS,UPON COMPLETION CONPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ; STACK SEGMENT =================================================== STACK SEGMENT DB PARA STACK 'STACK' 64 DUP ('*STACK*') STACK ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DB DATA ENDS 81 DUP('*') ;CODE SEGMENT CODE ===================================================== SEGMENT PARA PUBLIC 'CODE' 293 ASSUME MAIN CS:CODE, SS:STACK PROC FAR PUSH MOV PUSH DS AX,0 AX MOV AX,DATA MOV DS,AX ASSUME DS:DATA BINPUT_STR <OFFSET IO_BUF>,10,'#' BDSPLY_IMMED_STR <13,10,10> BINPUT_STR <OFFSET IO_BUF>, , , R BDSPLY_STR <OFFSET IO_BUF>, , R RET MAIN ENDP CODE ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 9-9 PAGE 55,80 COMMENT | PROGRAM : PROGRAMMER : DATE : PA9-9.ASM KADIR GECKIN 13/12/2000 BINPUT_STRL,BDSPLY_STRL VE BDSPLY_IMMED_STR YAPITASLARI KULLANILARAK BIOS ARACILIGIYLA KUYRUKTA SAKLI IKI STRING GIREN VE GOSTEREN PROGRAM INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ;STACK SEGMENT ================================================= STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP('*') ENDS ;DATA SEGMENT ===================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DATA DB ENDS ;CODE SEGMENT CODE 81 ================================================== SEGMENT PARA PUBLIC 'CODE' ASSUME MAIN DUP('*') PROC CS:CODE, SS:STACK FAR 294 PUSH DS MOV PUSH AX,0 AX MOV MOV ASSUME AX,DATA DS,AX DS:DATA BINPUT_STRL <OFFSET IO_BUF>,10 BDSPLY_STRL <OFFSET IO_BUF> DSPLY_IMMED_STR <13,10,10> BINPUT_STRL <OFFSET IO_BUF>, , R BDSPLY_STRL <OFFSET IO_BUF>, R RET MAIN CODE ENDP ENDS END MAIN 295 ASSEMBLY PROGRAM ÖRNEKLERİ BÖLÜM-5: COMMENT | CNV_UNC_STR MACRO ======================================== ISARETSIZ TAMSAYI DEGERLERINI BIR KUYRUKLA BIR ASCII SAYISAL STRINGINE CEVIRIR $CNV_UNS_STR PROSEDURU ILE INPUT PARAMETERS: BFR_OFF = OFFSET OF BUFFER TO HOLD ASCII-NUMERIC STRING WORD, REG OR IMMEDIATE MUST BE AT LEAST 1 BYTE LONGER THAN MAXIMUM NUMBER OF DIGITS UNS_INT = UNSIGNED INTEGER TO BE CONVERTED WORD,REG OR IMMEDIATE BASE = NUMERIC BASE FOR CONVERSION BYTE,REG OR IMMEDIATE DEFAULT = 10 TRAILER = CHARACTER TO USE AS STRING TRAILER BYTE,REGISTER OR IMMEDIATE DEFAULT = NUL CHARACTER (0) OUTPUT PARAMETERS: NONE ALL REGISTERS RESTORED | CNV_UNS_STR MACRO BFR_OFF,UNS_INT,BASE,TRAILER IFNDEF $CNV_UNS_STR EXTRN $CNV_UNS_STR:NEAR ENDIF PUSH SUB MOV BP SP,6 BP,SP MOV MOV WORD PTR [BP+0],BFR_OFF WORD PTR [BP+2],UNS_INT IFB <BASE> MOV BYTE PTR ELSE MOV BYTE PTR ENDIF IFB <TRAILER> MOV BYTE PTR ELSE MOV BYTE PTR ENDIF CALL [BP+4],10 [BP+4],BASE [BP+5],0 [BP+5],TRAILER $CNV_UNS_STR POP BP ENDM 296 COMMENT | CNV_UNS_STRL MACRO ======================================== ISARETSIZ TAMSAYIYI BIR BYTE OLARAK SAKLI BIR ASCII STRINGINE CEVIRIR. $CNV_UNS_STRL'Y˜ KULLANAN PROSEDUR INPUT PARAMETERS: BFR_PTR = OFFSET OF BUFFER TO HOLD ASCII-NUMERIC STRING WORD, REG OR IMMEDIATE MUST BE AT LEAST 1 BYTE LONGER THAN MAXIMUM NUMBER OF DIGITS UNS_INT = UNSIGNED INTEGER TO BE CONVERTED WORD, REG OR IMMEDIATE BASE = NUMERIC BASE FOR CONVERSION BYTE,BASE OR IMMEDIATE DEFAULT = 10 OUTPUT PARAMETERS: NONE ALL REGISTERS RESTORED | CNV_UNS_STRL MACRO BFR_OFF,UNS_INT,BASE IFNDEF $CNV_UNS_STRL EXTRN $CNV_UNS_STRL:NEAR ENDIF PUSH SUB MOV BP SP,5 BP,SP MOV MOV WORD PTR [BP+0],BFR_OFF WORD PTR [BP+2],UNS_INT IFB <BASE> MOV BYTE PTR ELSE MOV BYTE PTR ENDIF IFB <TRAILER> MOV BYTE PTR ELSE MOV BYTE PTR ENDIF [BP+4],10 [BP+4],BASE [BP+5],0 [BP+5],TRAILER CALL $CNV_UNS_STR POP BP ENDM COMMENT | CNV_UNS_STRL MACRO ========================================== ISARETLI TAMSAYIYI KUYRUKTA SAKLI BIR ASCII SAYISAL STRINGE CEVIRIR VE EGER NEGAT˜FSE ™NšNE EKS˜ EKLER $CNV_INT_STR PROSDEDURU ˜LE INPUT PARAMETERS: BFR_OFF = OFFSET OF BUFFER TO HOLD ASCII-NUMERIC STRING 297 WORD, REG OR IMMEDIATE MUST BE AT LEAST 1 BYTE LONGER THAN MAXIMUM NUMBER OF DIGITS INT = UNSIGNED INTEGER TO BE CONVERTED WORD, REG OR IMMEDIATE BASE = NUMERIC BASE FOR CONVERSION BYTE, REG OR IMMEDIATE DEFAULT = 10 TRAILER = CHARACTER TO USE AS STRING TRAILER BYTE, REGISTER OR IMMEDIATE DEFAULT = NUL CHARACTER (0) OUTPUT PARAMETERS: NONE ALL REGISTERS RESTORED | CNV_INT_STR MACRO BFR_OFF, INT, BASE,TRAILER IFNDEF $CNV_INT_STR EXTRN $CNV_INT_STR:NEAR ENDIF PUSH SUB MOV BP SP,6 BP,SP MOV MOV WORD PTR [BP+0],BFR_OFF WORD PTR [BP+2],INT IFB <BASE> MOV BYTE PTR ELSE MOV BYTE PTR ENDIF IFB <TRAILER> MOV BYTE PTR ELSE MOV BYTE PTR ENDIF CALL POP [BP+4],10 [BP+4],BASE [BP+5],0 [BP+5],TRAILER $CNV_INT_STR BP ENDM COMMENT | CNV_INT_STRL MACRO ============================================ ISARETLI TAMSAYIYI BIR BYTE UZUNLUGUNDA BIR ASCII SAYISAL STRINGE CEVIRIR VE EGER NEGAT˜FSE ™NšNE EKS˜ EKLER $CNV_INT_STRL PROSDEDURU ˜LE INPUT PARAMETERS: BFR_OFF = OFFSET OF BUFFER TO HOLD ASCII-NUMERIC STRING WORD, REG OR IMMEDIATE MUST BE AT LEAST 1 BYTE LONGER THAN MAXIMUM NUNBER OF DIGITS INT = UNSIGNED INTEGER TO BE CONVERTED WORD, REG OR IMMEDIATE 298 BASE = NUMERIC BASE FOR CONVERSION BYTE, REG OR IMMEDIATE DEFAULT = 10 OUTPUT PARAMETERS: NONE ALL REGISTERS RESTORED | CNV_INT_STRL MACRO BFR_OFF, INT, BASE IFNDEF $CNV_INT_STRL EXTRN $CNV_INT_STRL:NEAR ENDIF PUSH SUB MOV BP SP,5 BP,SP MOV MOV WORD PTR [BP+0],BPR_OFF WORD PTR [BP+2],INT IFB <BASE> MOV BYTE PTR [BP+4],10 ELSE MOV BYTE PTR [BP+4],BASE ENDIF CALL $CNV_INT_STRL POP ENDM BP COMMENT | CNV_STR_UNS MACRO ========================================= KUYRUKTA SAKLI BIR SAYISAL STRINGI ISARETSIZ TAMSAYIYA CEVIRIR CONSOLE.LIB ˜€˜NDE $CNV_STR_UNS PROSEDURU KULLANILARAK INCLUDE PARAMETERS: STR_OFF = OFFSET OF ASCII-NUMERIC STRING WORD, REG OR IMMEDIATE BASE = NUMERIC BASE (FOR CONVERSION) BYTE, REG OR IMMEDIATE DEFAULT = 10 TRAILER = CHARACTER USED TO MARK END OF STRING BYTE,REG OR IMMEDIATE DEFAULT = NUL CHARACTER (0) OUTPUT PARAMETERS: UNS_INT = UNSIGNED-INTEGER RESULT WORD, REGISTER ONLY CARRY FLAG CLEARED IF SECCUSSFUL, SET IF STRING IS INVALID ALL REGISTERS RESTORED | CNV_STR_UNS MACRO STR_OFF, UNS_INT, BASE, TRAILER IFNDEF $CNV_STR_UNS 299 EXTRN ENDIF PUSH SUB MOV $CNV_STR_UNS:NEAR BP SP,4 BP,SP MOV IFB WORD PTR [BP+0],STR_OFF <BASE> MOV BYTE PTR [BP+2],10 ELSE MOV BYTE PTR [BP+2],BASE ENDIF MOV BYTE PTR [BP+3],0 ELSE MOV BYTE PTR [BP+3],TRAILER ENDIF CALL $CNV_STR_UNS MOV INC INC POP UNS_INT, [BP+2] SP SP BP ENDM COMMENT | CNV_STRL_UNS MACRO ====================================== BIR BYTE UZUNLUGUNDA BIR SAYISAL STRINGI ISARETSIZ TAMSAYIYA CEVIRIR CONSOLE.LIB ˜€˜NDE $CNV_STR_UNS PROSEDURU KULLANILARAK CONSOLE.LIB ˜€˜NDE $CNV_STRL_UNS PROSEDURU KULLANILARAK INPUT PARAMETERS: STR_OFF = OFFSET OF ASCII-NUMERIC STRING WORD, REG OR IMMEDIATE BASE = NUMERIC BASE (FOR CONVERSION) BYTE, REG OR IMMEDIATE DEFAULT = 10 OUTPUT PARAMETERS: UNS_INT = UNSIGNED-INTEGER RESULT WORD, REGISTER ONLY CARRY FLAG CLEARED IF SUCCESSFUL, SET IF STRING IS INVALID ALL REGISTERS RESTORED | CNV_STRL_UNS MACRO STR_OFF, UNS_INT,BASE IFNDEF $CNV_STRL_UNS EXTRN $CNV_STRL_UNS:NEAR ENDIF PUSH SUB MOV BP SP,3 BP,SP MOV IFB WORD PTR [BP+0],STR_OFF <BASE> MOV BYTE PTR [BP+2],10 ELSE 300 MOV ELSE BYTE PTR [BP+2],BASE CALL $CNV_STRL_UNS MOV INC INC POP UNS_INT, [BP+1] SP SP BP ENDM COMMENT | CNV_STR_INT MACRO KUYRUKTA SAKLI BIR ASCII SAYISAL STRINGINI ISAREETLI TAMSAYIYA CEVIRIR ('+'VEYA'-') ISARETLERINI KABUL EDER CONSOLE.LIB ICINDE $CNV_STR_INT PROSEDURU KULLANILARAK INPUT PARAMETERS: STR_OFF = OFFSET OF ASCII-NUMERIC STRING WORD, REG OR IMMEDIATE BASE = NUMERIC BASE (FOR CONVERSION) BYTE, REG OR IMMEDIATE DEFAULT = 10 (IF BLANK) TRAILER = CHARACTER USED TO MARK END OF STRING BYTE, REG OR IMMEDIATE DEFAULT = NUL (0) OUTPUT PARAMETERS: INT = SIGNED-INTEGER RESULT WORD, REGISTER ONLY CARRY FLAG CLEARED IF SUCCESSFUL, SET IF STRING IS INVALID ALL REGISTERS RESTORED | CNV_STR_INT MACRO STR_OFF,INT,BASE,TRAILER IFNDEF $CNV_STR_INT EXTRN $CNV_STR_INT:NEAR ENDIF PUSH SUB MOV BP SP,4 BP,SP MOV IFB WORD PTR [BP+0],STR_OFF <BASE> MOV BYTE PTR [BP+2],10 ELSE MOV BYTE PTR [BP+3],0 ELSE MOV BYTE PTR [BP+3],TRAILER ENDIF CALL MOV INC INC POP $CNV_STR_INT INT, [BP+2] SP SP BP 301 ENDM COMMENT | CNV_STRL_INT MACRO ======================================== BIR BYTE OLARAK SAKLI BIR ASCII SAYISAL STRINGINI ISAREETLI TAMSAYIYA CEVIRIR ('+'VEYA'-') ISARETLERINI KABUL EDER CONSOLE.LIB ICINDE $CNV_STR_INT PROSEDURU KULLANILARAK INPUT PARAMETERS: STR_OFF = OFFSET OF ASCII NUMARIC STRING WORD, REG OR IMMEDIATE BASE = NUMERIC BASE (FOR CONVERSITION) BYTE, REG OR IMMEDIATE DEFAULT = 10 (IF BLANK) OUTPUT PARAMETERS: INT = SIGNED-INTEGER RESULT WORD, REGISTER ONLY CARRY FLAG CLEARED IF SUCCESSFUL, SET IF STRING IS INVALID ALL REGISTERS RESTORED | CNV_STRL_INT MACRO STR_OFF, INT, BASE IFNDEF $CNV_STRL_INT EXTRN $CNV_STRL_INT:NEAR ENDIF PUSH SUB MOV BP SP,3 BP,SP MOV IFB WORD PTR [BP+0],STR_OFF <BASE> MOV BYTE PTR [BP+2],10 ELSE MOV BYTE PTR [BP+2],BASE ENDIF CALL $CNV_STRL_INT MOV INC INC POP INT,[BP+1] SP SP BP ENDM COMMENT | GET_STR_LEN MACRO ============================================= KUYRUKLA EN YUKSEK UZUNLUKTA STRINGLER ICIN 255 BYTE YER ELDE EDER CONSOLE.LIB ICINDE $GET_STR_LEN PROSEDURU KULLANILARAK INPUT PARAMETERS: STR_OFF = OFFSET OF STRING WORD, REG OR IMMEDIATE TRAILER = TRAILER CHARACTER MARKING END OF STRING BYTE, REGISTER OR IMMEDIATE DEFAULT: NUL (0) OUTPUT PARAMETERS: 302 STR_LEN = LENGHT OF THE STRING BYTE, REG ONLY CARRY CLEARED IF TRAILER FOUND, SET IF NOT FOUND ALL REGISTERED RESTORED | GET_STR_LEN MACRO STR_OFF, STR_LEN_TRAILER IFNDEF $GET_STR_LEN EXTRN $GET_STR_LEN:NEAR ENDIF PUSH SUB MOV BP SP,3 BP,SP MOV IFB WORD PTR [BP+0],STR_OFF <TRAILER> MOV BYTE PTR [BP+2],0 ELSE MOV BYTE PTR [BP+2],TRAILER ENDIF CALL $GET_STR_LEN MOV STR_LEN, BYTE PTR [BP+2] INC POP SP BP ENDM COMMENT | $INT_STL.ASM KADIR GECKIN BIR ISARETLI TAMSAYIYI BIR BYTELA SAKLI ASCII SAYISAL STRINGINE CEVIREN PROSEDUR CNV_UNS_STRL MACRO TARAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF BUFFER TO RECEIVE THE STRING WORD AT [BP+0] SIGNED INTEGER TO BE CONVERTED WORD AT [BP+2] BASE TO USE IN CONVERSION BYTE AT [BP+4] OUTPUT PARAMETERS NONE ALL REGISTER RESTORED | 303 TITLE PAGE DATA $INT_STL.ASM 55,80 SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME $CNV_INT_STRL CS:CODE PROC NEAR PUBLIC $CNV_INT_STRL CNV_LP: CNV_1: PUSH PUSH PUSH PUSH PUSH AX CX DX DI ES MOV MOV MOV MOV MOV AX,[BP+2] BL,[BP+4] BH,0 DI,BX CX,0 MOV CMP JGE MOV NEG BL,'+' AX,0 CNV_LP BL, '-' AX MOV DIV DX,0 DI ADD CMP JBE ADD DL, '0' DL, '9' CNV_1 DL, 7 PUSH INC CMP JA DX CX AX, 0 CNV_LP PUSH POP MOV MOV STOSB DS ES DI,[BP] AL,CL CMP BL, '-' JNE STR_LP INC BYTE PTR ES:[DI-1] MOV AL,BL STOSB STR_LP: POP AX 304 STOSB LOOP POP POP POP POP POP POP RET $CNV_INT_STRL CODE COMMENT STR_LP ES DI DX CX BX AX 5 ENDP ENDS END | $INT_STR.ASM KADIR GECKIN BIR ISARETLI TAMSAYIYI KUYRUKLA SAKLI ASCII SAYISAL STRINGINE CEVIREN PROSEDUR CNV_UNS_STR MACRO TARAFINDAN KULLANILIR INTPUT PARAMETERS: OFFSET OF BUFFER TO RECEIVE THE STRING WORD AT [BP+0] SIGNED INTEGER TO BE CONVERTED WORD AT [BP+2] BASE TO USE IN CONVERSION BYTE AT [BP+4] TRAILER TO MARK END OF STRING BYTE AT [BP+5] OUTPUT PARAMETERS: NONE ALL REGISTERS RESTORED; STACK HOLE CLOSED | TITLE $INT_STR.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME $CNV_INT_STR CS:CODE PROC NEAR PUBLIC $CNV_INT_STR 305 CNV_LP: CNV_1: PUSH PUSH PUSH PUSH PUSH PUSH AX BX CX DX DI ES MOV MOV MOV MOV MOV AX, [BP+2] BL, [BP+4] BH,0 DI,BX CX,0 MOV CMP JGE MOV NEG BL,'+' AX,0 CNV_LP BL,'-' AX MOV DIV DX,0 DI ADD CMP JBE ADD DL, '0' DL, '9' CNV_1 DL,7 PUSH INC CMP JA DX CX AX, 0 CNV_LP PUSH DS POP ES MOV DI, [BP] CMP BL,'-' JNE STR_LP MOV AL,BL STOSB POP AX STR_LP: STOSB LOOP STR_LP MOV AL, [BP+5] STOSB POP POP POP POP POP POP RET $CNV_INT_STR CODE COMMENT | ES DI DX CX BX AX 6 ENDP ENDS END $STL_INT.ASM 306 KADIR GECKIN BYTELA SAKLI SAKLI BIR ASCII-SAYISAL STRINGINI ISARETLI TAMSAYIYA CEVIREN PROSEDUR CNV_STRL_INT MACRO INPUT PARAMETERS: OFFSET OF THE STRING TO BE CONVERTED WORD AT [BP+0] BASE TO USE IN CONNVERSION BYTE AT [BP+2] OUTPUT PARAMETERS: SIGNED INTEGER RESULTING FROM CONVERSION WORD AT [BP+1] CARRY FLAG CLEARED IF SUCCESFUL, SET IF STRING IS INVALID 2 BYTES OF STACK HOLE LEFT OPEN ALL OTHER REGISTER RESTORED | TITLE $STL_INT.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME $CNV_STRL_INT CS:CODE PROC NEAR PUBLIC $CNV_STRL_INT PUSH PUSH PUSH PUSH PUSH PUSH AX BX CX DX SI DI MOV MOV MOV MOV MOV MOV SI, BL, BH, DI, AX, BH, MOV MOV INC JCXZ CL, [SI] CH, 0 SI CNV_DONE CMP BYTE PTR [SI], '-' [BP] [BP+2] 0 BX 0 0 307 JE CMP JNE CNV_1: BEG_CLP: CNV_1 BYTE PTR [SI], '+' BEG_CLP INC SI DEC CX JCXZ END_CLP MOV INC BL, [SI] SI MUL JC SUB JB CMP DI CNV_INV BL,'0' CNV_INV BL,10 JB CNV_3: CNV_3 SUB BL, 7 CMP BL, 10 JB CNV_INV CMP BX,DI JAE CNV_INV ADD AX,BX JC CNV_INV LOOP BEG_CLP END_CLP: MOV SI,[BP] CMP JNE BYTE PTR [SI+1], '-' CNV_4 CMP JA NEG AX,32768 CNV_INV AX JMP SHORT CNV_DONE CMP AX, 32768 JAE CNV_INV MOV [BP+1],AX CLC JMP SHORT CNV_RET MOV WORD PTR [BP+1],0 STC POP DI POP SI POP DX POP CX POP BX POP AX RET 1 CNV_4: CNV_DONE: CNV_INV: CNV_RET: $CNV_STRL_INT ENDP CODE ENDS END COMMENT | $STL_UNS.ASM KADIR GECKIN 308 BIR BYTELA SAKLI BIR ASCII-SAYISAL STRINGINI ISARETSIZ TAMSAYIYA CEVIREN PROSEDUR CNV_STR_UNS MACRO TARAFINDAN KULLANILIR INPUT PARAMETERS OFFSET OF THE STRING TO BE CONVERTED WORD AT [BP+0] BASER TO USE IN CONVERSION BYTE AT [BP+2] OUTPUT PARAMETERS: UNSIGNED INTEGER RESULTING FORM CONVERSION WORD AT [BP+1] CARRY FLAG CLEARED IF SUCCESSFUL, SET IF STRING IS INVALID 2 BYTES OF STACK HOLE LEFT OPEN ALL OTHER REGISTER RESTORED | TITLE $STL_UNS.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME $CNV_STRL_UNS CS:CODE PROC NEAR PUBLIC $CNV_STRL_UNS CNV_LP: PUSH PUSH PUSH PUSH PUSH PUSH AX BX CX DX SI DI MOV MOV MOV MOV MOV MOV SI, BL, BH, DI, AX, BH, MOV MOV INC JCXZ CL, [SI] CH, 0 SI CNV_DONE [BP] [BP+2] 0 BX 0 0 MOV INC BL,[SI] SI MUL DI 309 JC SUB JB CMP BL,10 JB CNV_1 SUB BL,7 CMP BL,10 JB CNV_INV CMP BX,DI JAE CNV_INV ADD AX,CX CNV_1: JC CNV_INV LOOP CNV_LP MOV [BP+1],AX CLC JMP SHORT CNV_RET MOV WORD PTR [BP+1],0 STC POP DI POP SI POP DX POP CX POP BX POP AX CNV_DONE: CNV_INV: CNV_RET: RET $CNV_STRL_UNS CODE COMMENT CNV_INV BL, '0' CNV_INV 1 ENDP ENDS END | $STR_INT.ASM KADIR GECKIN KUYRUKLA SAKLI BIR ASCII-SAYISAL STRINGINI ISARETLI TAMSAYIYA CEVIREN PROSEDUR CNV_STR_INT MACRO INPUT PARAMETERS: OFFSET OF THE STRING TO BE CONVERTED WORD AT [BP+0] BASE TO USE IN CONVERSION BYTE AT [BP+2] TRAILER MARKING END OF STRING BYTE AT [BP+3] OUTPUT PARAMETERS: SIGNED INTEGER RESULTING FROM CONVERSION WORD AT [BP+2] CARRY FLAG CLEARED IF SUCCESSFUL, SET IF STRING IS INVALID 310 2 BYTES OF STACK HOLE LEFT OPEN ALL OTHER REGISTERS RESTORED | TITLE $STR_INT.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME $CNV_STR_INT CS:CODE PROC NEAR PUBLIC $CNV_STR_INT CNV_1: CNV_LP: PUSH PUSH PUSH PUSH PUSH PUSH AX BX CX DX SI DI MOV MOV MOV MOV MOV MOV SI, BL, BH, DI, AX, CH, MOV INC CL, [SI] SI MOV CMP JE CMP JNE MOV MOV BL,'+' CL,'-' CNV_1 CL,BL CNV_LP BL,CL CL, [SI] INC SI CMP CL, [BP+3] JE CNV_DONE MUL DI JC SUB JB CMP CNV_INV CL, '0' CNV_INV CL,10 JB SUB CMP JB [BP] [BP+2] 0 BX 0 0 CNV_3 CL,7 CL,10 CNV_INV 311 CMP CL,10 JB CNV_3 SUB CL,7 CMP CL,10 JB CNV_INV CX,DI CNV_INV AX,CX CNV_INV CL,[SI] SI CNV_LP CNV_3: CMP JAE ADD JC MOV INC JMP CNV_DONE: CMP BL,'-' JNE CNV_4 CMP AX, 32768 JA CNV_INV NEG AX JMP SHORT CNV_5 CMP AX,32768 JAE CNV_INV MOV [BP+2],AX CLC JMP SHORT CNV_RET MOV WORD PTR [BP+2],0 STC CNV_4: CNV_5: CNV_INV: CNV_RET: $CNV_STR_INT CODE POP POP POP POP POP POP RET DI SI DX CX BX AX 2 ENDP ENDS END COMMENT | $STR_LEN.ASM KADIR GECKIN KUYRUKTA SAKLI STRINGIN BYTE'INI ALAN PROSEDUR GET_STR_LEN MACRO TARAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF THE STRING WORD AT [BP+0] TRAILER ON END OF STRING BYTE AT [BP+2] OUTPUT PARAMETERS: NUMBER OF CHARACTER IN STRING (MAXIMUM OF 255) 312 BYTE AT [BP+2] CARRY CLEARED IF TRAILER FOUND SET IF NOT FOUND 1 BYTE OF STACK HOLE LEFT OPEN ALL OTHER REGISTERS | TITLE $STR_LEN.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME $GET_STR_LEN CS:CODE PROC NEAR PUBLIC $GET_STR_LEN FOUND: GSL_RET: PUSH PUSH PUSH PUSH PUSH POP MOV MOV AX CX DI ES DS ES DI, [BP+0] AL, [BP+2] MOV CX, 256 CLD REPNE SCASB JZ FOUND STC JMP SHORT GSL_RET SUB CX,255 NEG CX CLC MOV [BP+2],CL POP ES POP DI POP CX POP AX RET 2 $GET_STR_LEN ENDP CODE ENDS END COMMENT | $STR_UNS.ASM 313 KADIR GECKIN KUYRUKLA SAKLI BIR ASCII-SAYISAL STRINGINI ISARETSIZ TAMSAYIYA CEVIREN PROSEDUR CNV_STR_UNS MACRO TARAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF THE STRING TO BE CONVERTED WORD AT [BP+0] BASE TO USE IN CONVERSION BYTE AT [BP+2] TRAILER MARKING END OF STRING BYTE AT [BP+3] OUTPUT PARAMETERS: UNSIGNED INTEGER RESULTING FROM CONVERSION WORD AT [BP+2] CARY FLAG CLEARED IF SUCCESSFUL, SET IF STRING IS INVALID 2 BYTE OF STACK HOLE LEFT OPEN ALL OTHER REGISTER RESTORED | TITLE $STR_UNS.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME DS:CODE CODE ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME $CNV_STR_UNS CS:CODE PROC NEAR PUBLIC $CNV_STR_UNS CNV_LP: PUSH PUSH PUSH PUSH PUSH AX BX CX DX SI MOV MOV MOV MOV MOV SI, BL, BH, AX, CH, MOV [BP] [BP+2] 0 0 0 CL, [SI] 314 CNV_1: INC CMP JE SI CL,[BP+3] CNV_DONE MUL BX JC SUB JB CNV_INV CL, '0' CNV_INV CMP CL,10 JB CNV_1 SUB CL,7 CMP CL,10 JB CNV_INV CMP CL,BL JAE CNV_INV ADD AX,CX JC JMP CNV_DONE: CNV_INV: CNV_RET: $CNV_STR_UNS CODE CNV_INV CNV_LP MOV [BP+2],AX CLC JMP SHORT CNV_RET MOV WORD PTR [BP+2],0 STC POP SI POP DX POP CX POP BX POP AX RET 2 ENDP ENDS END COMMENT | $UNS_STL.ASM KADIR GECKIN BIR ISARETSIZ TAMSAYIYI BIR BYTELA SAKLI ASCII SAYISAL STRINGINE CEVIREN PROSEDUR CNV_UNS_STRL MACRO TARAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF BUFFER TO RECEIVE THE STRING WORD AT [BP+0] UNSIGNED INTEGER TO CONVERTED WORD AT [BP+2] BASE TO USE IN CONVERSION BYTE AT [BP+4] OUTPUT PARAMETERS: NONE ALL REGISTERS RESTORED; STACK HOLE CLOSED 315 | TITLE PAGE DATA $UNS_STL.ASM 55,80 SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $CNV_UNS_STRL PROC NEAR PUBLIC $CNV_UNS_STRL CNV_LP: CNV_1: PUSH PUSH PUSH PUSH MOV MOV MOV AX BX CX DX AX,[BP+2] BL,[BP+4] BH,0 MOV CX,0 MOV DIV DX,0 BX ADD DL, '0' CMP JBE ADD DL,'9' CNV_1 DL,7 PUSH INC CMP JA DX CX AX,0 CNV_LP MOV MOV INC BX,[BP] [BX],CL BX STR_LP: POP POP POP POP RET AX CX BX AX 5 $CNV_UNS_STRL CODE ENDP ENDS END COMMENT | $UNS_STR.ASM 316 KADIR GECKIN BIR ISARETSIZ TAMSAYIYI BIR KUYRUKLA SAKLI ASCII SAYISAL STRINGINE CEVIREN PROSEDUR CNV_UNS_STR MACRO TARAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF BUFFER TO RECEIVE THE STRING WORD AT [BP+0] UNSIGNED INTEGER TO BE CONVERTED WORD AT [BP+2] BASE TO USE IN CONVERSION BYTE AT [BP+4] TRAILER TO MARK ENBD OF STRING BYTE AT [BP+5] OUTPUT PARAMETERS: NONE ALL REGISTERS RESTORED; STACK HOLE CLOSED | TITLE $UNS_STR.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DATA CODE DS:DATA ENDS SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $CNV_UNS_STR PROC NEAR PUBLIC $CNV_UNS_STR CNV_LP: CNV_1: PUSH PUSH PUSH PUSH MOV MOV MOV MOV AX BX CX DX AX, BL, BH, CX, MOV DIV DX, 0 BX ADD CMP JBE ADD DL, '0' DL, '9' CNV_1 DL,7 PUSH INC CMP JA DX CX AX,0 CNV_LP [BP+2] [BP+4] 0 0 317 STR_LP: MOV POP BX, [BP] AX MOV INC LOOP MOV MOV [BX],AL BX STR_LP AL,[BP+5] [BX],AL POP POP POP POP RET DX CX BX AX 6 $CNV_UNS_STR CODE ENDP ENDS END TITLE PROGRAMMMING ASSIGNMENT 10-1 PAGE 55,80 COMMENT | PROGRAM: PA10-1.ASM PROGRAMMER: KADIR GECKIN DATE: 16/12/2000 BAZI ISARETSIZ TAM SAYILARI KUYRUKLA SAKLI STRINGLERE CEVIREN VE SONUC STRINGLERI GOSTERIR CNV_UNS_STR, DSPLY_STR VE DSPLY_IMMED_STR YAPITAžLARI KULLANILIR INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ;STACK SEGMENT ====================================================== STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') STACK ENDS ;DATA SEGMENT ======================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT ====================================================== 318 DATA SEGMENT PARA PUBLIC 'CODE' IO_BUF DATA DB 17 DUP('*') ENDS ;CODE SEGMENT ================================================== CODE SEGMENT PARA PUBLIC 'CODE' MAIN ASSUME CS:CODE, SS:STACK PROC FAR PUSH MOV PUSH MOV ASSUME DS AX, 0 AX, DATA DS,AX DS:DATA DSPLY_IMMED_STR <13,10,'Decimal 43690 = Binary'> CNV_UNS_STR <OFFSET IO_BUF>, 43690, 2, '*' DSPLY_IMMED_STR <13,10, 'Decimal 36480=Octal'> MOV DI,36408 CNV_UNS_STR <OFFSET IO_BUF>, DI, 8 DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <13,10,'Hex F09C =Decimal'> CNV_UNS_STR <OFFSET IO_BUF>,DI,8 DSPLY_STR <OFFSET IO-BUF> DSPLY_IMMED_STR <13,10, 'Decimal 61596 = Hex'> MOV CL,16 MOV BX, 61596 CNV_UNS_STR <OFFSET IO_BUF>, BX, CL DSPLY_STR <OFFSET IO_BUF> RET MAIN ENDP CODE ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 10-2 PAGE 55,80 COMMENT | PROGRAM : PA10-2.ASM PROGRAMMER : KADIR GECKIN DATE : 17/12/2000 BAZI ISARETLI TAM SAYILARI KUYRUKLA SAKLI STRINGLERE CEVIREN VE SONUC STRINGLERI GOSTERIR CNV_INT_STR, DSPLY_STR VE DSPLY_IMMED_STR YAPITAžLARI KULLANILIR 319 INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') STACK ENDS ;DATA SEGMENT =============================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DB DATA ENDS ;CODE SEGMENT PARA PUBLIC 'CODE' MAIN 18 DUP('*') ASSUME CS:CODE, SS:STACK PROC FAR PUSH DS MOV PUSH AX,0 AX MOV MOV ASSUME AX, DATA DS,AX DS:DATA DSPLY_IMMED_STR CNV_INT_STR DSPLY_STR DSPLY_STR <13,10,'Decimal 32767 = Binary'> <OFFSET IO_BUF>, +32767,2,'*' <OFFSET IO_BUF>, '*' <OFFSET IO_BUF> DSPLY_IMMED_STR DSPLY_IMMED_STR CNV_INT_STR DSPLY_STR <13,10,'Unsigned-hex F09C='> 'Signed-decimal' <OFFSET IO_BUF>,F09H <OFFSET IO_BUF> DSPLY_IMMED_STR <13,10, 'Decimal - 31596= Hex'> MOV CL,16 MOV BX, -31596 CNV_INT_STR <OFFSET IO_BUF>,BX,CL DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <13,10, 'Octal 17652 = Hex'> MOV CL, 16 MOV BX, 176520 CNV_INT_STR <OFFSET IO_BUF>,BX,CL DSPLY_STR <OFFSET IO_BUF> MAIN CODE RET ENDP ENDS 320 END MAIN TITLE PROGRAMMING ASSINGMENT 10-3 PAGE 55,80 COMMENT | PROGRAM : PA10-3.ASM PROGRAMMER : KADIR GECKIN DATE : 17/12/2000 BAZI ISARETSIZ TAM SAYILARI BYTE'LA SAKLI STRINGLERE CEVIREN VE SONUC STRINGLERI GOSTERIR CNV_UNS_STR, DSPLY_STR VE DSPLY_IMMED_STR YAPITAžLARI KULLANILIR INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS,UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ;STACK STACK SEGMENT ====================================================== SEGMENT PARA STACK 'STACK' DB STACK DUP ('*STACK*') ENDS ;DATA SEGMENT ====================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DATA DB 17 DUP ('*') ENDS ;CODE SEGMENT ======================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH DS MOV PUSH AX,0 AX MOV MOV ASSUME AX,DATA DS,AX DS:DATA DSPLY_IMMED_STR<13,10,'Decimal 43690 = Binary '> CNV_UNS_STRL <OFFSET IO_BUF>,43690, 2 DSPLY_STRL <OFFSET IO_BUF> 321 DSPLY_IMMED_STR <13,10, 'Decimal 36408 = Octal'> MOV DI, 36408 CNV_UNS_STRL <OFFSET IO_BUF>,DI,8 DSPLY_STRL <OFFSET IO_BUF> DSPLY_IMMED_STR <13,10, 'Hex F09C = Decimal'> CNV_UNS_STRL <OFFSET IO_BUF>, 0F09CH DSPLY_STRL <OFFSET IO_BUF> DSPLY_IMMED_STR CNV_UNS_STRL DSPLY_STRL <13,10, 'Hex F09C = Decimal'> <OFFSET IO_BUF>, 0F09CH <OFFSET IO_BUF> DSPLY_IMMED_STR <13,10,'Hex F09CH = Decimal'> CNV_UNS_STRL <OFFSET IO_BUF>, 0F09CH DSPLY_STRL <OFFSET IO_BUF> DSPLY_IMMED_STR <13,10,'Hex F09C = Decimal'> CNV_UNS_STRL <OFFSET IO_BUF>,0F09CH DSPLY_STRL <OFFSET IO_BUF> DSPLY_IMMED_STR <13,10, 'Decimal 61596 = Hex'> MOV CL, 16 MOV BX, 61596 CNV_UNS_STRL <OFFSET IO_BUF>,BX,CL DSPLY_STRL <OFFSET IO_BUF> RET MAIN CODE ENDP ENDS END MAIN TITLE PAGE COMMENT | PROGRAMING ASSINGMENT 10-4 55,80 PROGRAM : PA10-4.ASM PROGRAMMER : KADIR GECKIN DATE : 17/12/2000 BAZI ISARETLI TAM SAYILARI BYTE'LA SAKLI STRINGLERE CEVIREN VE SONUC STRINGLERI GOSTERIR CNV_INT_STRL, DSPLY_STRL VE DSPLY_IMMED_STR YAPITAžLARI KULLANILIR INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS,UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF ;STACK DATA SEGMENT ====================================================== SEGMENT PARA PUBLIC 'DATA' 322 DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT ========================================================= DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DB DATA ENDS ;CODE CODE 18 DUP ('*') SEGMENT ======================================================= SEGMENT PARA PUBLIC 'CODE' ASSUME MAIN CS:CODE, SS:STACK PROC FAR PUSH DS MOV PUSH AX,0 AX MOV MOV ASSUME AX,DATA DS, AX DS:DATA DSPLY_IMMED_STR <13,10, 'Decimal 32767 = Binary'> CNV_INT_STRL <OFFSET IO_BUF>, +32767, 2 DSPLY_STRL <OFFSET IO_BUF>, DSPLY_IMMED_STR <13,10, 'Decimal -14312 = Octal'> MOV DI, -14312 CNV_INT_STRL <OFFSET IO_BUF>,DI ,8 DSPLY_STRL <OFFSET IO_BUF> DSPLY_IMMED_STR DSPLY_IMMED_STR CNV_INT_STRL DSPLY_STRL <13,10, 'Unsigned-hex F09C ='> 'Signed-decimal' <OFFSET IO_BUF>,0F09CH <OFFSET IO_BUF> DSPLY_IMMED_STR <13,10, 'Decimal -31596 = Hex'> MOV CL, 16 MOV BX, -31596 CNV_INT_STRL <OFFSET IO_BUF>,BX,CL DSPLY_STRL <OFFSET IO_BUF> RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMING ASSINGMENT 10-5 323 PAGE COMMENT | 55,80 PROGRAM : PA10-5.ASM PROGRAMMER : KADIR GECKIN DATE : 18/12/2000 BAZI ISARETSIZ SAYISAL GIRIS CIKIS DEGERLERINI SAKLAR TUM STRINGLER KUYRUKTA SAKLANIR. INPUT_STR, CNV_STR_UNS, CNV_UNS_STR, DSPLY_STR VE DSPLY_IMMED_STR YAPITASLARI KULLANILIR INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS,UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') STACK ENDS DATA SEGMENT PARA STACK 'DATA' IO_BUF DB 8 DUP ('*') INV_MSG DEC_MSG DB DB 7, 'Invalid - Try again', 13, 10, 10, 0 'in base 10',13,10,10,0 DATA ENDS CODE SEGMENT PARA PUBLIC 'CODE' ASSUME MAIN GET_HEX: DSP_HEX: GET_OCT: CS:CODE, SS:STACK PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX,0 AX AX,DATA DS,AX DS:DATA DSPLY_IMMED_STR <'Unsigned base 16 numeral?'> INPUT_STR <OFFSET IO_BUF>, 6, '%' CNV_STR_UNS <OFFSET IO_BUF>, CX, 16, '%' JNC DSP_HEX DSPLY_STR <OFFSET INV_MSG> JMP GET_HEX CNV_UNS_STR <OFFSET IO_BUF>,CX DSPLY_STR <OFFSET IO_BUF> DSPLY_STR <OFFSET DEC_MSG> DSPLY_IMMED_STR <'Unsigned base 8 numeral?'> INPUT_STR <OFFSET IO_BUF>,7 MOV BL ,8 CNV_STR_UNS <OFFSET IO_BUF>, SI, BL 324 JNC DSP_OCT DSPLY_STR JMP GET_OCT DSP_OCT: CNV_UNS_STR DSPLY_STR DSPLY_STR <OFFSET INV_MSG> <OFFSET IO_BUF>,SI <OFFSET IO_BUF> <OFFSET DEC_MSG> RET MAIN ENDP ENDS END MAIN TITLE PAGE COMMENT | PROGRAMING ASSINGMENT 10-6 55,80 PROGRAM : PA10-6.ASM PROGRAMMER : KADIR GECKIN DATE : 18/12/2000 BAZI ISARETLI SAYISAL GIRIS CIKIS DEGERLERINI SAKLAR TUM STRINGLER KUYRUKTA SAKLANIR. INPUT_STR, CNV_STR_INT, CNV_INT_STR, DSPLY_STR VE DSPLY_IMMED_STR YAPITASLARI KULLANILIR INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS,UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') STACK ENDS DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DB 9 DUP('*') INV_MSG DEC_MSG DB DB 7, 'Invalid - Try Again',13, 10, 10, 0 ' in base 10', 13, 10, 10, 0 DATA ENDS CODE SEGMENT PARA PUBLIC 'CODE' MAIN ASSUME CS:CODE, SS:STACK PROC FAR PUSH MOV DS AX,0 325 PUSH MOV MOV ASSUME GET_HEX: AX AX,DATA DS,AX DS:DATA DSPLY_IMMED_STR INPUT_STR CNV_STR_INT JNC DSP_HEX DSPLY_STR JMP GET_HEX CNV_INV_STR DSPLY_STR DSPLY_STR DSP_HEX GET_OCT: <'Signed base 16 numeral?'> <OFFSET IO_BUF>,7,'%' <OFFSET IO_BUF>,CX,16,'%' <OFFSET INV_MSG> <OFFSET IO_BUF>,CX <OFFSET IO_BUF> <OFFSET DEC_MSG> DSPLY_IMMED_STR <'Signed base 8 numeral?'> INPUT_STR <OFFSET IO_BUF>,8 MOV BL, 8 CNV_STR_INT <OFFSET IO_BUF>,SI,BL JNC DSP_OCT DSPLY_STR <OFFSET INV_MSG> JMP GET_OCT CNV_INT_STR <OFFSET IO_BUF>,SI DSPLY_STR <OFFSET IO_BUF> DSPLY_STR <OFFSET DEC_MSG> DSP_OCT RET MAIN CODE ENDP ENDS END MAIN TITLE PAGE COMMENT | PROGRAMING ASSINGMENT 10-7 55,80 PROGRAM : PA10-7.ASM PROGRAMMER : KADIR GECKIN DATE : 18/12/2000 BAZI ISARETSIZ SAYISAL GIRIS CIKIS DEGERLERINI SAKLAR TUM STRINGLER BYTLE'LA SAKLANIR INPUT_STRL, CNV_STRL_UNS, CNV_UNS_STR, DSPLY_STRL VE DSPLY_IMMED_STR YAPITASLARI KULLANILIR INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS,UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS 326 DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF INV_MSG DM_END DB DB DB EQU DB DB EQU DATA ENDS CODE SEGMENT PARA PUBLIC 'CODE' IM_END DEC_MSG 8 DUP('*') IM_END - $ - 1 7, 'Invalid - Try again',13, 10, 10 $ DM_END - $ - 1 ' in base 10',13 ,10, 10 $ ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX,0 AX AX,DATA DS,AX DS:DATA GET_HEX: DSPLY_IMMED_STR <'Unsigned base 16 numeral?'> INPUT_STRL <OFFSET IO_BUF>, 6 CNV_STRL_UNS <OFFSET IO_BUF>,CX,16 JNC DSP_HEX DSPLY_STRL <OFFSET INV_MSG> JMP GET_HEX CNV_UNS_STRL <OFFSET IO_BUF>,CX DSPLY_STRL <OFFSET IO_BUF> DSPLY_STRL <OFFSET DEC_MSG> DSP_HEX: GET_OCT: DSPLY_IMMED_STR <'Unsigned base 8 numeral?'> INPUT_STRL <OFFSET IO_BUF>,SI DSPLY_STRL <OFFSET IO_BUF> DSPLY_STRL <OFFSET DEC_MSG> RET MAIN CODE ENDP ENDS END TITLE PAGE COMMENT | MAIN PROGRAMING ASSINGMENT 10-8 55,80 PROGRAM : PA10-8.ASM PROGRAMMER : KADIR GECKIN DATE : 18/12/2000 BAZI ISARETLI SAYISAL GIRIS CIKIS DEGERLERINI SAKLAR TUM STRINGLER BYTLE'LA SAKLANIR INPUT_STRL, CNV_STRL_INT, CNV_INT_STRL, DSPLY_STRL VE 327 DSPLY_IMMED_STR YAPITASLARI KULLANILIR INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS,UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF STACK STACK DATA IO_BUF INV_MSG SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') ENDS DM_END SEGMENT PARA PUBLIC 'DATA' DB 9 DUP ('*') DB IM_END - $ - 1 DB 7, 'Invalid - Try again', 13, 10, 10 EQU $ DB DM_END - $ - 1 DB ' in base 10', 10 ,13, 10, 10 EQU $ DATA ENDS CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC PUSH MOV PUSH MOV MOV ASSUME IM_END GET_HEX: FAR DS AX,0 AX AX,DATA DS,AX DS:DATA DSPLY_IMMED_STR <'Signed base 16 numeral?'> INPUT_STRL <OFFSET IO_BUF>, 7 CNV_STRL_INT <OFFSET IO_BUF>, CX, 16 JNC DSP_HEX DSPLY_STRL <OFFSET INV_MSG> JMP GET_OCT CNV_INT_STRL <OFFSET IO_BUF>,SI DSPLY_STRL <OFFSET IO_BUF> DSPLY_STRL <OFFSET DEC_MSG> DSP_OCT: RET ENDP ENDS END MAIN MAIN CODE TITLE PAGE COMMENT | PROGRAMING ASSINGMENT 10-9 55,80 PROGRAM : PA10-9.ASM PROGRAMMER : KADIR GECKIN DATE : 18/12/2000 328 BIR TABANDAN DIGERINE ISARETSIZ TAMSAYILARI CEVIREN PROGRAM INPUT_STRL, CNV_STRL_INT, CNV_INT_STRL, DSPLY_STRL VE DSPLY_IMMED_STR YAPITASLARI KULLANILIR INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS,UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF STACK STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') ENDS DATA IO_BUF I_BASE Q_BASE INV DATA SEGMENT PARA PUBLIC 'DATA' DB 17 DUP('*') DB 3 DUP('I') DB 3 DUP('O') DB DB 'Invalid numeral -Try again',0 ENDS CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX,DATA DS,AX DS:DATA GET_IBASE: IB_INV: GET_OBASE: OB_INV: BEG_LP: DSPLY_IMMED_STR <13,10, 'Base for input?'> INPUT_STR <OFFSET I_BASE>, 2 CNV_STR_UNS <OFFSET I_BASE>, AX JC IB_INV CMB AX ,2 JAE GET_OBASE DSPLY_STR <OFFSET INV_MSG> JMP GET_IBASE DSPLY_IMMED_STR <13,10,'Base for output?'> INPUT_STR <OFFSET O_BASE>, 2 CNV_STR_UNS <OFFSET O_BASE>, BX JC OB_INV CMP BX, 2 JAE BEG_LP DSPLY_STR <OFFSET INV_MSG> JMP GET_OBASE DSPLY_IMMED_STR <13,10,10, 'Base '> DSPLY_STR <OFFSET I_BASE> DSPLY_IMMED_STR 'unsigned integer' DSPLY_IMMED_STR '(0 to quit)?' INPUT_STR <OFFSET IO_BUF>,16 CNV_STR_UNS <OFFSET IO_BUF>, CX, AL JNC INT_OK DSPLY_STR <OFFSET INV_MSG> 329 INT_OK JMP CMP JE BEG_LP CX,0 END_LP CNV_UNS_STR <OFFSET IO_BUF>, CX, BL DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR 'in base' DSPLY_STR <OFFSET O_BASE> JMP BEG_LP END_LP: RET MAIN CODE ENDP ENDS END MAIN TITLE PAGE COMMENT | PROGRAMING ASSINGMENT 10-10 55,80 PROGRAM : PA10-10.ASM PROGRAMMER : KADIR GECKIN DATE : 18/12/2000 BIR TABANDAN DIGERINE ISARETLI TAMSAYILARI CEVIREN PROGRAM INPUT_STR, CNV_STR_UNS, CNV_STR_INT, CNV_INT_STR, DSPLY_STRL VE DSPLY_IMMED_STR YAPITASLARI KULLANILIR INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS,UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF STACK STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') ENDS DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF I_BASE O_BASE INV_MSG DB DB DB DB DATA ENDS CODE SEGMENT PARA PUBLIC 'CODE' 17 DUP ('*') 3 DUP ('I') 3 DUP ('O') 7, 'Invalid numeral - Try again',0 ASSUME MAIN CS:CODE, SS:STACK PROC NEAR PUSH DS MOV AX,0 330 PUSH AX MOV AX,DATA MOV DS,AX ASSUME DS:DATA GET_IBASE: IB_INV: DSPLY_IMMED_STR <13,10, 'Base for input?'> INPUT_STR <OFFSET I_BASE>, 2 CNV_STR_UNS <OFFSET I_BASE>, AX JC OB_INV CMP BX, 2 JAE GEG_LP DSPLY_STR <OFFSET INV_MSG> JMP GET_IBASE GET_OBASE: JMP BEG_LP: JNC END_LP MAIN CODE JMP RET DSPLY_STR <OFFSET INV_MSG> GET_OBASE DSPLY_IMMED_STR DSPLY_STR DSPLY_IMMED_STR DSPLY_IMMED_STR INPUT_STR CNV_STR_INT INT_OK DSPLY_STR BEG_LP <13,10,10,'Base'> <OFFSET I_BASE> 'signed integer' '0 to quit)' <OFFSET IO_BUF>,16 <OFFSET IO_BUF>,CX, AL <OFFSET INV_MSG> ENDP ENDS END MAIN TITLE PAGE COMMENT | PROGRAMING ASSINGMENT 10-11 55,80 PROGRAM : PA10-11.ASM PROGRAMMER : KADIR GECKIN DATE : 18/12/2000 STRINGIN BYTE'INI RAPOR EDEN PROGRAM INPUT_STR, GET_STR_LEN, CNV_UNS_STR, DSPLY_STR VE DSPLY_IMMED_STR YAPITASLARI KULLANILIR INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS,UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB ENDIF STACK STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') ENDS DATA SEGMENT PARA PUBLIC 'DATA' 331 IO_BUF DATA DB 256 DUP ('*') ENDS CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX,0 AX AX,DATA DS,AX DS:DATA DSPLY_IMMED_STR 'Enter up to 255 characters:' DSPLY_IMMED_STR <13,10> INPUT_STR <OFFSET IO_BUF>, 255 GET_STR_LEN <OFFSET IO_BUF>, AL JC NOT_FOUND MOV AH, 0 CNV_UNS_STR <OFFSET IO_BUF>,AX DSPLY_IMMED_STR 'You entered' DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <' character(s).',13,10> JMP SHORT M_RET NOT_FOUND: DSPLY_IMMED_STR <7, 'Trailer not found!',13, 10> M_RET: RET MAIN CODE ENDP ENDS END MAIN TITLE PAGE COMMENT | PROGRAMING ASSINGMENT 10-12 55,80 PROGRAM : PA10-12.ASM PROGRAMMER : KADIR GECKIN DATE : 18/12/2000 STRING GIREN PROGRAM, STRINGI TASIR VE SONRA IKINCI KOPYASINI GOSTERIR INPUT_STR, GET_STR_LEN, DSPLY_STR VE DSPLY_IMMED_STR YAPITASLARI KULLANILIR INPUT_STRL, DSPLY_STRL, DSPLY_IMMED_STR YAPITASLARININ DEGISSIK SURUMLERI KULLANILIYOR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURN TO DOS,UPON COMPLETION | IF1 332 INCLUDE CONSOLE.MLB ENDIF STACK STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') ENDS DATA SEGMENT PARA PUBLIC 'DATA' BUF_1 BUF_2 BUF_3 DB DB DB DATA ENDS CODE SEGMENT PARA PUBLIC 'CODE' MAIN 81 DUP ('*') 81 DUP ('*') 4 DUP ('%') ASSUME CS:CODE, SS:STACK PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX,DATA DS,AX DS:DATA DSPLY_IMMED_STR <7, 'Trailer not found!',13, 10> RET ENDP M_RET: MAIN COMMENT | STRINGLERIN BYTLE'LA SAKLANDIGI DAHA SONRA KUYRUKLA SAKLNADIGI IZLEYEN YENI SURUMU | MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX,0 AX AX,DATA DS,AX DS:DATA DSPLY_IMMED_STRL 'Enter up to 80 characters:' DSPLY_IMMED_STRL <13,10> INPUT_STRL <OFFSET BUF_1>,80 MOV CL, BUF_1 MOV CH, 0 INC CX CALL MOVE_IT DSPLY_STRL <OFFSET BUF_2>; RET MAIN ENDP MOVE_IT PROC NEAR PUSH PUSH PUSH PUSH CX SI DI ES 333 DSPLY_IMMED_STR 'Moving' CNV_UNS_STR <OFFSET BUF_3>,CX DSPLY_STR <OFFSET BUF_3> DSPLY_IMMED_STR <'bytes',13,10> PUSH POP MOV MOV CLD REP POPF POP POP POP POP RET MOVE_IT CODE DS ES SI, OFFSET BUF_1 DI, OFFSET BUF_2 MOVSB ES DI SI CX ENDP ENDS END MAIN 334 ASSEMBLY PROGRAM ÖRNEKLERİ BÖLÜM-6: COMMENT | DISK.MLB KADIR GECKIN DISK DEPOLAMA ICIN MACRO KUTUPHANESI TO USE: INCLUDE DISK.MLB AT THE BEGINING OF THE MAIN LINE PROGRAM. IF USING MASM VERSION 1-4 REMARK OUT INCLUDELIB DIRECTIVE BELOW SPECIFY DISK.LIB AS THE LIBRARY FILE DURING LINK. MACROS INCLUDED IN THIS LIBRARY: RESET_DISK DRV, STAT GET_STATUS DRV, LAST_STAT READ_SCRT DRV,SIDE,TRAK, SCTR, NBR, BUFF_OFF,STAT WRITE_SCRT DRV,SIDE,TRAK, SCTR, NBR, BUFF_OFF,STAT VERIFY_SCRT DRV,SIDE,TRAK, SCTR, NBR, STAT GET_PRMS DRV,TYPE,SIDES,TRAK,SCRTS,NBR,NO_DRVS,STAT SEL_DEF DEF_DRV,NO_DRVS GET_DEF DEF_DRV SET_DTA DTA_OFF GET_DTA DTA_OFF, DTA_SEG GET_DSK_SPACE DRV, FRE_CL, TTL_CL, CL_SIZ, SCT_SIZ CNV_STRL_ASCZ STR_OFF MKDIR ASCZ_OFF, ERROR RMDIR ASCZ_OFF, ERROR CHDIR ASCZ_OFF, ERROR GET_DIR DRV, BUFF_OFF, ERROR CHG_ATT ASCZ_OFF, ATT, ERROR GET_ATT ASCZ_OFF, ATT, ERROR DEL_FILE ASCZ_OFF, ERROR REN_FILE OLDASCZ_OFF, NEWASCZ_OFF, ERROR DEFINE_DIR_BFR_STRUCT DIR_NXT ERROR OPEN_FILE ASCZ_OFF, MODE, HANDLE, ERROR CREATE_FILE ASCZ_OFF, ATT, HANDLE, ERROR READ_STREAM HANDLE, MODE, BUFF_OFF, ERROR WRITE_STREAM HANDLE, BYTES, BUFF_OFF, ERROR SEEK HANDLE, MODE, DISP_M, DISP_L, ERROR RSEEK HANDLE, MODE, R_LEN, R_DISP, ERROR READ_CHR HANDLE, CHR_ERR READ_STR HANDLE, BUFF_OFF, MAX_LEN, TRAILER, ERROR READ_STRL HANDLE, BUFF_OFF, MAX_LEN, ERROR WRITE_CHR HANDLE, CHAR, ERROR WRITE_STR HANDLE, STR_OFF, TRAILER, ERROR WRITE_STRL HANDLE, STR_OFF, ERROR DUP_HANDLE OLD_HANDLE, NEW_HANDLE, ERROR REDIR_HANDLE HADNLE_1, HANDLE_2, ERROR GET_TM&DT HANDLE, TIME, DATE, ERROR SET_TM&DT HANDLE, TIME, DATE, ERROR CLOSE_FILE HANDLE, ERROR | INCLUDELIB DISK COMMENT | RESET_DISK MACRO ============================================== 335 DISK DENETCI YOHGASINI SIFIRLAR DISK.LIB ICINDE $RESET_DISK YORDAMI KULLNILIR INPUT PARAMETERS: DRV = DRIVE TO RESET BYTE, REGISTER OR IMMEDIATE 00H - 7FH = FLOPPY DRIVES 80H - FFH = HARD DISKS DEFAULT = 00H (DRIVE A) OUTPUT PARAMETERS: STAT = STATUS RETURNED BY BIOS BYTE, REGISTER ONLY OPTIONAL PARAMETERS 00H 01H 02H 03H 04H 05H 06H 07H 08H 09H 0AH 0BH 0CH 0DH 0EH OFH 10H 11H 20H 40H 80H AAH BBH CCH E0H FFH = = = = = = = = = = = = = = = = = = = = = = = = = = Succesful. Unknown operation code Sector ID error (Bad addres mark). Write protect error. Sector not found. Hard-disk-controller reset failed Floppy disk removed. Bad parameter table. DMA overrun Attempt to cross 64K boundary Bad sector flag Bad track flag Media type not found. Invalid number number of sector on format. Control-data address mark detected. DMA arbitration level out of range. Bad CRC or ECC ECC-corrected data error. NEC disk drive controller failure. Seek operation failure. Time_out. Drive not ready Undefined error. Write fault. Status-register error. Sense operation failed. CARRY FLAG CLEAR IF SECCUESFUL, SET IF ERROR | RESET_DISK MACRO DRV,STAT IFNDEF $RESET_DISK:NEAR EXTRN $RESET_DISK:NEAR ENDIF PUSH BP DEC SP MOV BP,SP IFB <DRV> MOV BYTE PTR [BP+0], 0 ELSE MOV BYTE PTR [BP+0], DRV ENDIF CALL $RESET_DISK IFNB <STAT> MOV STAT, BYTE PTR [BP+0] ENDIF INC SP 336 POP BP ENDM COMMENT | GET_STATUS MACRO =============================================== EN SON DISK ISLEVININ DURUMUNU ALIR. DISK.LIB ICINDE $GET_STATUS YORDAMI KULLANILIR. INPUT PARAMETERS: DRV = DRIVE TO RESET BYTE, REGISTER OR IMMEDIATE 00H - 7FH = FLOPPY DRIVES 80H - FFH = HARD DISKS DEFAULT = A OUTPUT PARAMETERS: LAST_STAT = STATUS RETURNED BY LAST BIOS DISK OPERATION BYTE, REGISTER ONLY SEE RESET_DISK FOR INTERPRETION OF STATUS GET_STATUS MACRO DRV, LAST_STAT IFNDEF $GET_STATUS EXTRN $GET_STATUS:NEAR ENDIF PUSH BP DEC SP MOV BP,SP IFB <DRV> MOV BYTE PTR [BP+0], 0 ELSE MOV BYTE PTR [BP+0], DRV ENDIF CALL $GET_STATUS MOV LAST_STAT, BYTE PTR [BP+0] INC POP ENDM SP BP COMMENT | READ_SCRT MACRO ============================================= BIR YA DA DAHA FAZLA DISK SEKTORU OKUR (HICBIR DOSYA DUZENLENMEMIS) DISK.LIB ICINDE $READ_SCTR YORDAMI KULLANILIR. INPUT PARAMETERS: DRV = DRIVE TO READ FROM BYTE, REGISTER OR IMMEDIATE 00H - 7FH = FLOPPY DRIVES 80H - FFH = HARD DISKS DEFAULT = A SIDE = DISK SIDE TO READ FROM (0 = 1ST SIDE) BYTE, REGISTER OR IMMEDIATE TRAK = TRACK TO READ FROM (0 = 1 ST TRACK) BYTE, REGISTER OR IMMEDIATE SCRT = SECTOR AT WHICH TO BEGIN READ (1 = 1 ST SECTOR) BYTE, REGISTER OR IMMEDIATE NRB = NUMBER OF SECTOR TO READ BYTE, REGISTER OR IMMEDIATE BUFF_OFF = OFFSET OF BUFFER TO RECEIVE DATA WORD, REGISTER OR IMMEDIATE 337 MUST BE AT LEAST NBR*512 BYTES OUTPUT PARAMETERS: STAT = STATUS RETURNED BY BIOS BYTE, REGISTER ONLY OPTIONAL PARAMETER SEE RESET_DISK FOR INTRPERATION OF STAT IFNDEF $READ_SCTR EXTRN $READ_SCTR:NEAR ENDIF PUSH BP SUB SP,7 MOV BP, SP IFB <DRV> MOV BYTE PTR [BP+0], 0 ELSE MOV BYTE PTR [BP+0], DRV ENDIF MOV BYTE PTR [BP+1],SIDE MOV BYTE PTR [BP+2],TRAK MOV BYTE PTR [BP+3],SCTR MOV BYTE PTR [BP+4],NBR MOV WORD PTR [BP+5],BUFF_OFF CALL $READ_SCTR IFNB <STAT> MOV STAT, BYTE PTR [BP+6] ENDIF INC SP POP BP ENDM COMMENT | WRITE_SCRT MACRO ============================================== BIR YA DA DAHA FAZLA DISK SEKTORU YAZAR (HICBIR DOSYA DUZENLENMEMIS) DISK.LIB ICINDE $WRITE_SCTR YORDAMI KULLANILIR. INPUT PARAMETERS: DRV = DRIVE TO WRITE TO BYTE, REGISTER OR IMMEDIATE 00H - 7FH = FLOPPY DRIVES 80H - FFH = HARD DISKS DEFAULT = A SIDE = DISK SIDE TO WRITE TO (0 = 1ST SIDE) BYTE, REGISTER OR IMMEDIATE TRAK = TRACK TO WRITE TO (0 = 1 ST TRACK) BYTE, REGISTER OR IMMEDIATE SCRT = SECTOR AT WHICH TO BEGIN WRITE (1 = 1 ST SECTOR) BYTE, REGISTER OR IMMEDIATE NRB = NUMBER OF SECTOR TO READ BYTE, REGISTER OR IMMEDIATE BUFF_OFF = OFFSET OF BUFFER TO RECEIVE DATA WORD, REGISTER OR IMMEDIATE MUST BE AT LEAST NBR*512 BYTES OUTPUT PARAMETERS: STAT = STATUS RETURNED BY BIOS BYTE, REGISTER ONLY OPTIONAL PARAMETER SEE RESET_DISK FOR INTRPERATION OF STAT IFNDEF $WRITE_SCTR 338 EXTRN ENDIF $WRITE_SCTR:NEAR PUSH BP SUB SP,7 MOV BP, SP IFB <DRV> MOV BYTE PTR [BP+0], 0 ELSE MOV BYTE PTR [BP+0], DRV ENDIF MOV BYTE PTR [BP+1],SIDE MOV BYTE PTR [BP+2],TRAK MOV BYTE PTR [BP+3],SCTR MOV BYTE PTR [BP+4],NBR MOV WORD PTR [BP+5],BUFF_OFF CALL $WRITE_SCTR IFNB <STAT> MOV STAT, BYTE PTR [BP+6] ENDIF INC SP POP BP ENDM COMMENT | VERIFY_SCRT MACRO ============================================= BIR YA DA DAHA FAZLA DISK SEKTORU DOGRULAR (HICBIR DOSYA DUZENLENMEMIS) DISK.LIB ICINDE $VERIFY_SCTR YORDAMI KULLANILIR. INPUT PARAMETERS: DRV = DRIVE TO VERIFY BYTE, REGISTER OR IMMEDIATE 00H - 7FH = FLOPPY DRIVES 80H - FFH = HARD DISKS DEFAULT = A SIDE = DISK SIDE TO VERIFY (0 = 1ST SIDE) BYTE, REGISTER OR IMMEDIATE TRAK = TRACK TO VERIFY (0 = 1 ST TRACK) BYTE, REGISTER OR IMMEDIATE SCRT = SECTOR AT WHICH TO BEGIN VERIFY (1 = 1 ST SECTOR) BYTE, REGISTER OR IMMEDIATE NRB = NUMBER OF SECTOR TO VERIFY BYTE, REGISTER OR IMMEDIATE BUFF_OFF = OFFSET OF BUFFER TO RECEIVE DATA WORD, REGISTER OR IMMEDIATE MUST BE AT LEAST NBR*512 BYTES OUTPUT PARAMETERS: STAT = STATUS RETURNED BY BIOS BYTE, REGISTER ONLY OPTIONAL PARAMETER SEE RESET_DISK FOR INTRPERATION OF STAT IFNDEF $VERIFY_SCTR EXTRN $VERIFY_SCTR:NEAR ENDIF PUSH BP SUB SP,7 MOV BP, SP IFB <DRV> MOV BYTE PTR [BP+0], 0 339 ELSE MOV BYTE PTR [BP+0], DRV ENDIF MOV BYTE PTR [BP+1],SIDE MOV BYTE PTR [BP+2],TRAK MOV BYTE PTR [BP+3],SCTR MOV BYTE PTR [BP+4],NBR MOV WORD PTR [BP+5],BUFF_OFF CALL $VERIFY_SCTR IFNB <STAT> MOV STAT, BYTE PTR [BP+6] ENDIF INC SP POP BP ENDM COMMENT | GET_PRMS MACRO ================================================ DISK SURUCU PARAMETRELERINI ALIR (SABIT DISK YALNIZ PC VEYA XT UZERINDE ISE, SABIT VEYA DISKET SURUCU AT VEYA PS/2 UZERINDE) DISK.LIB ICINDE $GET_PRMS YORDAMI KULLANILIR. INPUT PARAMETERS: DRV = DRIVE FOR WHICH TO GET PARAMETERS BYTE, REGISTER OR IMMEDIATE 00H - 7FH = FLOPPY DRIVES (AT $ PS/2 ONLY) 80H - FFH = HARD DISKS DEFAULT = A OUTPUT PARAMETERS: TYPE = DISKETTE-DRIVE TYPE BYTE, REGISTER ONLY OPTIONAL PARAMETER VALID ONLY FOR FLOPPY DRIVE ON PC/AT OR PS/2 SIDES = NUMBER OF SIDES ON THE DRIVE BYTE, REGISTER ONLY OPTIONAL PARAMETER TRAKS = NUMBER OF TRACKS PER SIDE WORD, REGISTER ONLY OPTIONAL PARAMETER SCTRS = NUMBER OF SECTORS PER TRACK BYTE, REGISTER ONLY OPTIONAL PARAMETER NO_DRVS = NUMBER OF PHYSICAL DRIVES (FLOPPY OR HARD DISK) BYTE, REGISTER ONLY OPTIONAL PARAMETER STAT = STATUS RETURNED BY BIOS BYTE, REGISTER ONLY OPTIONAL PARAMETER SEE RESET_DISK FOR INTERPRETATION OF STAT CARRY FLAG CLEAR IF SUCCESSFUL, SET IF ERROR | GET_PRMS MACRO DRV,TYPE,SIDES,TRACK,SCRTRS,NO_DRVS,STAT IFNDEF $GET_PRMS EXTRN $GET_PRMS:NEAR ENDIF 340 PUSH BP SUB SP ,7 MOV BP,SP IFB <DRV> MOV BYTE PTR [BP+0], 0 ELSE MOV BYTE PTR [BP+0], DRV ENDIF CALL $GET_PRMS IFNB <TYPE> MOV TYPE,BYTE PTR [BP+0] ENDIF IFNB <SIDES> MOV SIDES, BYTE PTR [BP+1] ENDIF IFNB <TRACKS> MOV TRACKS, WORD PTR [BP+2] ENDIF IFNB <STRCS> MOV STRCS, BYTE PTR [BP+4] ENDIF IFNB <NO_DRVS> MOV NO_DRVS, BYTE PTR [BP+5] ENDIF IFNB <STAT> MOV STAT, BYTE PTR [BP+6] ENDIF INC SP INC SP INC SP INC SP INC SP INC SP INC SP POP BP ENDM COMMENT | $GET_PRM.ASM KADIR GECKIN DISK SURUCUSUNUN PARAMETRELERINI ALAN ALTYORDAM GET_PRMS MACRO TARAFINDAN KULLANILIR INPUT PARAMETERS: DRIVE (00H - 7FH = FLOPPY, 80H -FFH = HARD) BYTE AT [BP+0] 341 OUTPUT PARAMETERS: TYPE OF DISKETTE DRIVE (VALID ONLY FOR FLOPPY DRIVE ON PC/AT OR PS/S) BYTE AT [BP+0] SIDES ON DRIVE BYTE AT [BP+1] TRACK PER SIDE WORD AT [BP+2] SECTOR PER TRACK BYTE AT [BP+4] NUMBER OF PHYSICAL DRIVES (FLOPPY OR HARD) BYTE AT [BP+5] STATUS RETURNED BY BIOS BYTE AT [BP+6] CARRY FLAG CLEARED IF SUCCESFUL IF UNSUCCESSFULL (ATTEMPTED ON PC OR XT FOR EXAMPLE), CARRY FLAG IS SET AND ALL PARAMETERS EXCEPT STAT ARE MAININGLESS 1- BYTE OF STACK HOLE LEFT OPEN ALL OTHER REGISTER RESTORED | TITLE $GET_PRM.ASM PAGE 55,80 DATA DATA CODE SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA ENDS SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $GET_PRMS PROC NEAR PUBLIC $GET_PRMS PUSH PUSH PUSH PUSH PUSH PUSH MOV MOV INT AX BX CX DX DI ES DL, [BP+0] AH, 08H 13H JC MOV INC GP_1 [BP+0], BL DH MOV [BP+1], DH MOV MOV ROL ROL AND INC MOV AND BL, CH BH, CL BH, 1 BH, 1 BH, 03H BX [BP+2], BX CL, 3FH 342 MOV MOV CLC MOV POP POP POP POP POP POP RET GP_1: $GET_PRMS CODE COMMENT [BP+4], CL [BP+5], DL [BP+6], AH ES DI DX CX BX AX ENDP ENDS END | $READ_SC.ASM KADIR GECKIN BIR YADA DAHA COK DISK SEKTORU OKUYAN ALTYORDAM (HICBIR DOSYA DUZENLENMEMIS) READ_SCTR MACRO TARAFINDAN KULLANILIR INPUT PARAMETERS: DRIVE TO READ FROM (00H - 7FH = FLOPPY, 80H- FFH = HARD) BYTE AT [BP+0] SIDE TO READ BYTE AT [BP+1] TRACK TO READ FROM BYTE AT [BP+3] OFFSET OF SECTORS TO READ BYTE AT [BP+4] OFFSET OF BUFFER TO RECEIVE DATA WORD AT [BP+5] OUTPUT PARAMETER: STATUS RETURNED BY BIOS BYTE AT [BP+6] 1-BYTE OF STACK HOLE LEFT OPEN ALL OTHER REGISTERS RESTORED | TITLE PAGE DATA $READ_SC.ASM 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' 343 ASSUME $READ_SCRT $READ_SCRT CODE CS:CODE PROC NEAR PUBLIC $READ_SCRT PUSH PUSH PUSH PUSH PUSH AX BX CX DX ES MOV MOV MOV MOV MOV MOV PUSH POP MOV INT MOV DL, [BP+0] DH, [BP+1] CH, [BP+2] CL, [BP+3] AL, [BP+4] BX, [BP+5] DS ES AH, 03H 13H [BP+6], AH POP POP POP POP POP RET ES DX CX BX AX 6 ENDP ENDS END COMMENT | $RST_DSK.ASM KADIR GECKIN DISK DENETCISINI SIFIRLAYAN ALTYORDAM RESET_DISK MACRO TARAFINDAN KULLANILIR. INPUT PARAMETERS: DRIVE TO RESET (00H - 7H = FLOPPY, 80H - FFH=HARD) BYTE AT [BP+0] OUTPUT PARAMETERS: STATUS RETURNED BY BIOS BYTE AT [BP+0] 1- BYTE STACK HOLE LEFT OPEN ALL OTHER REGSITERS RESTORED | TITLE PAGE DATA $RST_DSK.ASM 55,80 SEGMENT WORD PUBLIC 'DATA' 344 ASSUME ENDS DATA CS:CODE CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $RESET_DISK PROC NEAR PUBLIC $RESET_DISK $RESET_DISK CODE PUSH PUSH AX DX MOV MOV INT MOV DL, [BP+0] AH, 00H 13H [BP+0],AH POP POP RET DX AX ENDP ENDS END COMMENT | $STATUS.ASM KADIR GECKIN EN SON DISK ISLEMININ DURMUNU ALAN ALTYORDAM GET_STATUS MACRO TARAFINDAN KULLANILIR. INPUT PARAMTERS: DRIVE (00H - 7FH = FLOPPY, 80H - FFH = HARD) BYTE AT [BP+0] OUTPUT PARAMETERS: STATUS OF LAST DISK OPERATION BYTE AT [BP+0] 1- BYTE STACK HOLE LEFT OPEN ALL OTHER REGISTERS RESTORED | TITLE $STATUS.ASM PAGE 55,80 DATA DATA CODE $GET_STATUS SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA ENDS SEGMENT WORD PUBLIC 'DATA' ASSUME CS:CODE PROC NEAR PUBLIC $GET_STATUS 345 PUSH PUSH MOV MOV INT MOV POP POP RET $GET_STATUS CODE COMMENT | AX DX DL, [BP+0] AH, 01H 13H [BP+0],AL DX AX ENDP ENDS END $WRFY_SC.ASM KADIR GECKIN BIR YADA DAHA COK DISK SEKTORU DOGRULAYAN ALTYORDAM (HICBIR DOSYA DUZENLENMEMIS) WERIFY_SCTR MACRO TARAFINDAN KULLANILIR INPUT PARAMETERS: DRIVE TO WERIFY (00H - 7FH = FLOPPY, 80H- FFH = HARD) BYTE AT [BP+0] SIDE TO VERIFY BYTE AT [BP+1] TRACK TO VERIFY BYTE AT [BP+3] OFFSET OF SECTORS TO VERIFY BYTE AT [BP+4] OUTPUT PARAMETERS: STATUS RETURNED BY BIOS BYTE AT [BP+4] 1-BYTE OF STACK HOLE LEFT OPEN ALL OTHER REGISTERS RESTORED | TITLE PAGE DATA DATA CODE $WRITE_SC.ASM 55,80 SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA ENDS SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $VERIFY_SCRT PROC NEAR PUBLIC $VERIFY_SCRT 346 PUSH PUSH PUSH PUSH PUSH AX BX CX DX ES MOV MOV MOV MOV MOV DL, DH, CH, CL, AL, MOV INT MOV AH, 04H 13H [BP+4], AH POP POP POP RET DX CX AX 4 [BP+0] [BP+1] [BP+2] [BP+3] [BP+4] $VERIFY_SCRT ENDP CODE ENDS END COMMENT | $WRTE_SC.ASM KADIR GECKIN BIR YADA DAHA COK DISK SEKTORU YAZAN ALTYORDAM (HICBIR DOSYA DUZENLENMEMIS) WRITE_SCTR MACRO TARAFINDAN KULLANILIR INPUT PARAMETERS: DRIVE TO WRITE TO (00H - 7FH = FLOPPY, 80H- FFH = HARD) BYTE AT [BP+0] SIDE TO WRITE TO BYTE AT [BP+1] TRACK TO WRITE TO BYTE AT [BP+3] OFFSET OF SECTORS TO WRITE BYTE AT [BP+4] OFFSET OF BUFFER FROM WHICH TO WRITE DATA WORD AT [BP+5] OUTPUT PARAMETER: STATUS RETURNED BY BIOS BYTE AT [BP+6] 1-BYTE OF STACK HOLE LEFT OPEN ALL OTHER REGISTERS RESTORED 347 | TITLE PAGE DATA $WRITE_SC.ASM 55,80 SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA ENDS DATA CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $WRITE_SCRT PROC NEAR PUBLIC $WRITE_SCRT PUSH PUSH PUSH PUSH PUSH AX BX CX DX ES MOV MOV MOV MOV MOV MOV PUSH POP MOV INT MOV DL, [BP+0] DH, [BP+1] CH, [BP+2] CL, [BP+3] AL, [BP+4] BX, [BP+5] DS ES AH, 03H 13H [BP+6], AH POP POP POP POP POP RET ES DX CX BX AX 6 $WRITE_SCRT ENDP CODE ENDS END TITLE PROGRAMMING ASSINGMENT 11-1 PAGE 55,80 COMMENT | PROGRAM : PA11-1.ASM PROGRAMMER : KADIR GECKIN DATE : 20/12/2000 BIR SEKTOR OKUR VE GOSTERIR ICERIK PROGRAM ICERIK HEXADESIMAL ICINDE INPUT_STR, CNV_STR_UNS, CNV_UNS_STR, DSPLY_STR, DSPLY_IMMED_STR, READ_SCTR VE RESET_DISK YAPITASLARI KULLANILIR. INPUT PARAMETERS : NONE OUTPUT PARAMETERS : NONE 348 RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF STACK STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') ENDS DATA IO_BUF DSK_BUF INV_INT CR_LF SEGMENT DB DB DB DB DATA ENDS CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK PROC FAR MAIN PUSH MOV PUSH MOV MOV ASSUME GET_DRV: GET_SIDE: PARA PUBLIC 'DATA' 17 DUP('*') 512 DUP('#') 7, 'Invalid entry - Try again',13,10,10,0 13,10,0 DS AX,0 AX AX,DATA DS,AX DS:DATA DSPLY_IMMED_STR 'Drive nuber hexadecimal?' INPUT_STR <OFFSET IO_BUF> CNV_STR_UNS <OFFSET IO_BUF>,AX,16 MOV BH,AL JNC GET_SIDE DSPLY_STR <OFFSET IO_BUF> JMP GET_DRV DSPLY_IMMED_STR 'Side?' INPUT_STR <OFFSET IO_BUF> CNV_STR_UNS <OFFSET IO_BUF>,AX,16 MOV BH,AL JNC GET_TRAK DSPLY_STR <OFFSET INV_INT> JMP GET_SIDE GET_TRAK: DSPLY_IMMED_STR 'Track?' INPUT_STR <OFFSET IO_BUF> CNV_STR_UNS <OFFSET IO_BUF>,AX MOV BL,AL JNC GET_TRAK DSPLY_STR <OFFSET INV_INT> JMP GET_SIDE GET_SCTR: DSPLY_IMMED_STR 'Sector?' INTPUT_STR <OFFSET IO_BUF> CNV_STR_UNS <OFFSET IO_BUF>,AX MOV DL,AL JNC READ_DSK DSPLY_STR <OFFSET INV_INT> JMP GET_SCTR READ_DSK: MOV CX,4 349 RD_LP : DSP_SCTR: DSP_LP: DL_1: DL_2: DONE: MAIN CODE READ_SCTR BH,BL,DH JNC DSP_SCTR RESET_DISK BH LOOP RD_LP DSPLY_IMMED_STR <7, 'Unable to read sector - '> DSPLY_IMMED_STR 'Status:' MOV AH,0 CNV_UNS_STR <OFFSET IO_BUF>,AX,16 DSPLY_STR <OFFSET IO_BUF> DSPLY_CHR 'H' JMP DONE MOV CX,512 MOV SI, OFFSET DSK_BUF TEST CL,0FH JNZ DL_1 DSPLY_STR <OFFSET CR_LF> LODSB CMP AL,16 JAE DL_2 DSPLY_IMMED_STR '0' CNV_UNS_STR <OFFSET IO_BUF>,AX,16 DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR 'H' LOOP DSP_LP DSPLY_STR RET ENDP ENDS END MAIN <OFFSET CR_LF> TITLE PROGRAM ASSIGNMENT 11-2 PAGE 55,80 COMMENT | PROGRAM : PA11-2.ASM PROGRAMMER : KADIR GECKIN DATE : 20/12/2000 SABIT DISK VEYA FLOPPY DISKIN PARAMETERELERINI RAPOR EDER INPUT_STR, CNV_STR_UNS, CNV_UNS_STR, DSPLY_STR, DSPLY_IMMED_STR, READ_SCTR VE RESET_DISK YAPITASLARI KULLANILIR INPUT PARAMETERS : NONE OUTPUT PARAMETERS : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF STACK STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') ENDS 350 DATA IO_BUF DSK_BUF SIDES TRACKS SECTORS INV_INT CR_LF SEGMENT DB DB DW DW DW DB DB DATA ENDS CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK PROC FAR MAIN PUSH MOV PUSH MOV MOV ASSUME GET_DRV GET_PARAMS: HARD PARA PUBLIC 'DATA' 17 DUP('*') 512 DUP('#') 0 0 0 7, 'Invalid entry - Try again',13,10,10,0 13,10,0 DS AX,0 AX AX,DATA DS,AX DS:DATA DSPLY_IMMED_STR 'Drive INPUT_STR <OFFSET CNV_STR_UNS <OFFSET MOV BH,AL JNC GET_PARAMS DSPLY_STR <OFFSET JMP GET_DRV number (in hexadecimal)?' IO_BUF> IO_BUF>,AX,16 INV_INT> CMP BH,80H JAE HARD JMP FLOPPY DSPLY_IMMED_STR <13,10,'Hard disk',13,10> GET_PRMS BH, BL, CX ,DL, AL JNC GP_OK DSPLY_IMMED_STRV 'Unable to get parameters - ' DSPLY_IMMED_STR 'Status:' MOV AH,0 CNV_UNS_STR <OFFSET IO_BUF>,AX,16 DSPLY_STR <OFFSET IO_BUF> DSPLY_CHR 'H' JMP DONE GP_OK: MOV MOV MOV JMP FLOPPY: DSPLY_IMMED_STR <13,10, 'Floppy disk',13,10> MOV CX,4 READ_SCRT BH,0,0,2,1,<OFFSET DSK_BUF>,AL JNC F_1 RESET_DISK BH LOOP RD_LP DSPLY_IMMED_STR 'Unable to read FAT - Status:' MOV AH, 0 CNV_UNS_STR <OFFSET IO_BUF>,AX,16 DSPLY_STR <OFFSET IO_BUF> DSPLY_CHR 'H' JMP DONE RD_LP: BYTE PTR SIDES, BL TRACKS, CX BYTE PTR SECTORS, DL DSPLY_PARAMS 351 F_1: F_2: F_4: F_5: F_6: INV_FAT: F_7: FIVE: DSPLY_PARAMS: MOV AL, DSK_BUF MOV SIDES, 1 MOV TRACKS, 40 CMP AL, 0FCH JNE F_2 MOV SECTOR, 9 JMP DSPLY_PARAMS CMP AL, 0FEH JNE F_3 MOV SECTORS, 8 JMP SIDES, 2 CMP AL, OFDH JNE F_4 MOV SECTORS, 9 JMP DSPLY_PARAMS CMP AL, OFFH JNE F_5 MOV SECTOR, 8 JMP DSPLY_PARAMS MOV TRACKS, 80 CMP AL, 0F0H JNE F_6 MOV SECTORS, 8 JMP DSPLY_PARAMS CMP AL, 0F9H JE F_7 DSPLY_IMMED_STR <7, 'Invalid diskette FAT',13,10> JMP DONE GET_PRMS BH,AL JC FIVE CMP AL,3 JB FIVE MOV SECTORS, 9 JMP DSPLY_PARAMS MOV SECTORS, 15 MOV AX, SIDES CNV_UNS_STR <OFFSET IO_BUF>,AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <' sides', 13, 10> MOV AX, TRACKS CNV_UNS_STR <OFFSET IO_BUF>,AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <'tracks per side', 13, 10> MOV AX, SECTORS CNV_UNS_STR <OFFSET IO_BUF>,AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <'sectors per side',13,10> MOV AX,SIDES MUL SECTORS MUL TRACKS MOV BX, 2 DIV BX CNV_UNS_STR <OFFSET IO_BUF>, AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <'KB total capacitiy', 13, 10> DONE: MAIN CODE RET ENDP ENDS 352 END MAIN TITLE PROGRAM ASSIGNMENT 11-3 PAGE 55,80 COMMENT | PROGRAM : PA11-3.ASM PROGRAMMER : KADIR GECKIN DATE : 21/12/2000 MANTIKSAL SEKTORLERI OKUYAN VE GOSTEREN PROGRAM ICERIK HEXADESIMAL DE INPUT_STR, CNV_STR_UNS, CNV_UNS_STR, DSPLY_STR, DSPLY_IMMED_STR, READ_SCTR ,RESET_DISK VE GET_PRMS YAPITASLARI KULLANILIR INPUT PARAMETERS : NONE OUTPUT PARAMETERS : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF STACK STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') ENDS DATA IO_BUF DSK_BUF SIDES TRACKS SECTORS INV_INT CR_LF SEGMENT DB DB DW DW DW DB DB DATA ENDS CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK PROC FAR MAIN GET_DRV: PARA PUBLIC 'DATA' 17 DUP('*') 512 DUP('#') 0 0 0 7, 'Invalid entry - Try again',13,10,10,0 13,10,0 PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX ASSUME DS:DATA DSPLY_IMMED_STR 'Drive INPUT_STR <OFFSET CNV_STR_UNS <OFFSET MOV BH,AL JNC GET_LSCTR DSPLY_STR <OFFSET JMP GET_DRV number (in hexadecimal)?' IO_BUF> IO_BUF>,AX,16 INV_INT> 353 GET_LSCTR: DSPLY_IMMED_STR 'Logical sector number?' INPUT_STR <OFFSET IO_BUF> CNV_STR_UNS <OFFSET IO_BUF>,AX MOV DX,AX JNC GET_PARAMS DSPLY_STR <OFFSET INV_INT> JMP GET_LSCTR GET_PARAMS: CMP BH, 80H JB FLOPPY GET_PRMS BH, , BL, CX, AH, , AL MOV BYTE PTR SIDES, BL MOV TRACKS, CX MOV BYTE PTR SECTORS, AH JMP CALC_PHYS FLOPPY: MOV CX, 4 READ_SCTR BH, 0, 0, 2, 1,<OFFSET DSK_BUF>,AL JNC DSP_SCTR RESET_DISK BH LOOP RDSCT_LP DSPLY_IMMED_STR <7, Unable to read sector - '> DSPLY_IMMED_STR <'Status:'> MOV AH, 0 CNV_UNS_STR <OFFSET IO_BUF>, AX, 16 DSPLY_STR <OFFSET IO_BUF> DSPLY_CHR 'H' JMP DONE DSP_SCTR: MOV CX, 512 MOV SI, OFFSET DSK_BUF TEST CL, 0FH JNZ DL_1 DSPLY_STR <OFFSET CR_LF> LODSP CMP AL,16 JAE DL_2 DSPLY_IMMED_STR '0' CNV_UNS_STR <OFFSET IO_BUF>,AX,16 DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR 'H' LOOP DSP_LP DSP_LP: DL_1: DL_2: DONE: DSPLY_STR <OFFSET CR_LF> RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAM ASSIGNMENT 11-4 PAGE 55,80 COMMENT | PROGRAM : PA11-4.ASM PROGRAMMER : KADIR GECKIN DATE : 21/12/2000 354 SEKTORDEN SECTORE DISK KOPYALAYAN PROGRAM INPUT_STR, CNV_STR_UNS, CNV_UNS_STR, DSPLY_STR, DSPLY_IMMED_STR, READ_SCTR ,WRITE_SCTR, RESET_DISK VE GET_PRMS YAPITASLARI KULLANILIR INPUT PARAMETERS : NONE OUTPUT PARAMETERS : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF STACK STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') ENDS DATA IO_BUF DSK_BUF SEGMENT PARA PUBLIC 'DATA' DB 17 DUP('*') DB 18 * 512 DUP('#') SIDES TRACKS SECTORS S_TYPE D_TYPE INV_DRV DENS_ERR_MSG CR_LF DW DW DW DB DB DB DB DB DB DATA ENDS 0 0 0 ? ? 7, '˜nvalid drive - Try again',13,10,10,0 7, 'source is high density; destination' 'drive is not',0 13,10,0 CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV ASSUME GET_SRC: INV GET_DST DS AX,0 AX,DATA DS,AX DS:DATA DSPLY_IMMED_STR 'Drive number to copy from' DSPLY_IMMED '(0-127)?' INPUT_STR <OFFSET IO_BUF> CNV_STR_UNS <OFFSET IO_BUF>, AX MOV BH, AL JC INV_SRC CMP BH, 80H JB GET_DST DSPLY_STR <OFFSET IO_BUF> JMP GET_SRC DSPLY_IMMED_STR 'Drive number to copy to ' DSPLY_IMMED_STR '(0 -127)?' INPUT_STR <OFFSET IO_BUF> CNV_STR_UNS <OFFSET IO_BUF>, AX MOV BL, AL JC INV_DST CMP BL, 80H 355 JB INV_DST: DRV_TYPE: DT_1: DT_2: DT_3: DRV_TYPE DSPLY_STR <OFFSET INV_DRV> JMP GET_DST GET_PRMS BH, AL JNC DT_1 MOV AL, 1 MOV S_TYPE, AL GET_PRMS BL,AL JNC DT_2 MOV AL, 1 MOV CMP JB D_TYPE, AL S_TYPE, 3 DT_3 CMP JB JMP D_TYPE, 3 DIF_TYPE GET_FATS CMP JB D_TYPE, 3 GET_FATS GET_FATS: MOV CX, 4 SRC_FAT_LP: READ_SCTR BH,0,0,2,1,<OFFSET IO_BUF>,AL JNC GF_1 RESET_DISK BH LOOP SRC_FAT_LP DSPLY_IMMED_STR <7, 'Unable to read source FAT - '> DSPLY_IMMED_STR <7, 'Status:'> FAT_ERR: MOV AH,0 CNV_UNS_STR <OFFSET IO_BUF>, AX, 16 DSPLY_STR <OFFSET IO_BUF> DSPL_CHR 'H' JMP DONE GF_1: DH, DSK_BUF CX, 4 DST_FAT_LP: READ_SCTR BL,0,0,2,1, <OFFSET DSK_BUF>,AL JNC GF_2 RESET_DISK BL LOOP DST_FAT_LP DSPLY_IMMED_STR <7, 'Unable to read dest FAT - '> DSPLY_IMMED_STR 'Status: ' JMP FAT_ERR GF_2: MOV DL, DSK_BUF GET_PARAMS: GP_1: GP_2: MOV MOV MOV MOV CMP JNE MOV JMP CMP CMP MOV JMP MOV CMP JNE MOV JMP SIDES, 1 TRACK, 40 DH, 0FCH GP_1 SECTOR, 9 COPY_DISK DH, 0FEH GP_2 SECTOR, 8 COPY_DISK SIDES, 2 DH, OFDH GP_3 SECTOR, 9 COPY_DISK 356 GP_3: GP_4: GP_5: CMP JNE MOV JMP MOV CMP JNE CMP JB MOV JMP CMP DH, 0FFH GP_4 SECTORS, 8 COPY_DISK TRACKS, 80 DH, 0F0H GP_5 D_TYPE, 4 DENS_ERR SECTORS, 18 COPY_DISK DH, 0F9H JE GP_6 INV_FAT: DSPLY_IMMED_STR <7, 'Unknown diskette format'> JMP DONE GP_6: CMP S_TYPE, 3 JB GP_7 MOV SECTORS, 9 JMP COPY_DISK CMP D_TYPE, 2 JE GP_8 DSPLY_STR <OFFSET DENS_ERR_MSG> JMP DONE MOV SECTORS, 15 GP_7: DENS_ERR: GP_8: COPY_DISK: CPY_LP: DONE: DSPLY_IMMED_STR <13,10, 'Copying'> MOV AX,SIDES CNV_UNS_STR <OFFSET IO_BUF>,AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR ' side(s),' MOV AX, TRACKS CNV_UNS_STR <OFFSET IO_BUF>,AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR ' tracks per side,' MOV AX,SECTORS CNV_UNS_STR <OFFSET IO_BUF>,AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR ' sectors per track.', 13, 10> DSPLY_IMMED_STR <'. = 1 cylinder.',13 ,10> MOV DL, 0 MOV CX, TRACKS CALL COPY_CYL JC DONE INC DL LOOP CPY_CYL DSPLY_IMMED_STR <13,10, 'Copy complete'> DSPLY_STR <OFFSET CR_LF> RET ;---------------------------------------------------------------------COPY_CYL CC_LP: PROC NEAR PUSH CX PUSH DX DSPLY_CHR '.' MOV DH, 0 MOV CX, SIDES CALL COPY_TRAK 357 JC CC_RET: CC_RET INC DH LOOP CC_LP POP CC_LP POP DX POP CX RET COPY_CYL ENDP ;---------------------------------------------------------------------COPY_TRAK CT_RET: PROC CALL JC CALL RET COPY_TRAK ENDP NEAR READ_TRAK CL_RET WRITE_TRAK ;---------------------------------------------------------------------PUBLIC READ_TRAK READ_TRAK PROC NEAR PUSH PUSH MOV RT_1: RT_LP1: AX CX AH, BYTE PTR SECTORS CMP AH, 9 JBE RT_1 MOV AH, 9 MOV CX, 4 READ_SCTR BH,DH,DL,1,AH,<OFFSET DSK_BUF>,AL JNC RT_ERR: RT_2: RT_LP2: RT_2 RESET_DISK BH LOOP RT_LP1 DSPLY_IMMED_STR <7,13,10, 'Error reading source'> CALL DSPLY_STAT STC JMP RT_RET MOV AH, BYTE PTR SECTORS CMP AH, 9 JBE RT_DONE SUB AH, 9 MOV CX, 4 READ_SCRT BH,DH,DL,10,AH, <OFFSET DSK_BUF+9*512>,AL JNC RT_DONE: RT_RET: READ_TRAK RT_DONE RESET_DISK LOOP RT_LP2 JMP RT_ERR CLC POP CX POP AX RET BH ENDP ;----------------------------------------------------------------------WRITE_TRAK PROC NEAR 358 WT_1: WT_LP1: PUSH PUSH MOV AX CX AH, BYTE PTR SECTORS CMP JBE MOV AH, 9 WT_1 AH, 9 MOV CX, 4 WRITE_SCTR BL,DH,DL,1,AH <OFFSET DSK_BUF>,AL JNC WT_2 RESET_DISK BL LOOP WT_LP1 DSPLY_IMMED_STR <7,13,10, 'Error writing to'> DSPLY_IMMED_STR 'Destination' CALL DSPLY_STAT STC JMP WT_RET MOV AH, BYTE PTR SECTORS WT_ERR: WT_2: WT_LP2: CMP JBE AH, 9 WT_DONE SUB MOV AH, 9 CX, 4 WRITE_SCTR BL,DH,DL,10,AH <OFFSET DSK_BUF+9*512>,AL JNC WT_DONE RESET_DISK BL LOOP WT_LP2 JMP WT_ERR CLC POP CX POP AX RET WT_DONE: WT_RET: WRITE_TRACK ENDP ;----------------------------------------------------------------DSPLY_STAT PROC NEAR PUSH AX MOV AH, 0 DSPLY_IMMED_STR ' - Status: ' CNV_UNS_STR <OFFSET IO_BUF>, AX, 16 DSPLY_CHR <OFFSET IO_BUF> POP AX RET DSPLY_STAT CODE ENDP ENDS END MAIN TITLE PROGRAM ASSIGNMENT 11-5 359 PAGE COMMENT | 55,80 PROGRAM : PA11-5.ASM PROGRAMMER : KADIR GECKIN DATE : 23/12/2000 DISKET UZERINDE KOTU YA DA SIRALANMIS SEKTORKERIN NUMARASINI VEREN PROGRAM INPUT_STR, CNV_STR_UNS, CNV_UNS_STR, DSPLY_STR, DSPLY_IMMED_STR, READ_SCTR , RESET_DISK VE GET_PRMS YAPITASLARI KULLANILIR INPUT PARAMETERS : NONE OUTPUT PARAMETERS : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;STACK SEGMENT ======================================================== STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') STACK ENDS ;DATA SEGMENT ======================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DB 17 DUP('*') DSK_BUF DB 9 * 512 DUP ('#') FAT_SIZE CLST_SIZE INV_DRV DATA DB DB DB ENDS ? ? 7, ' Invalid drive - Try again',13,10,10,0 ;CODE SEGMENT ====================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:CODE MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX,DATA DS, AX DS:DATA GET_DRV: DRV_ERROR: M_1: LP_1: DSPLY_IMMED_STR 'Drive number (0 -127)?' INPUT_STR <OFFSET IO_BUF> CNV_STR_UNS <OFFSET IO_BUF>, AX MOV BH, AL JC DRV_ERROR CMP BH, 80H JB M_1 DSPLY_STR <OFFSET INV_DRV> JMP GET_DRV MOV CX, 4 READ_SCTR JNC M_2 BH,0,0,2,1,<OFFSET DSK_BUF>,AL 360 READ_ERR: M_2: M_3: M_4: M_5: M_6: M_7: RESET_DISK LOOP LP_1 DSPLY_IMMED_STR DSPLY_IMMED_STR MOV AH, 0 CNV_UNS_STR DSPLY_STR DSPLY_CHR JMP DONE MOV CMP JNE MOV MOV JMP CMP JNE MOV MOV JMP CMP JNE MOV MOV JMP CMP JNE MOV MOV JMP CMP JNE MOV MOV JMP CMP JE BH <7, 'Unable to read FAT - '> 'Status:' <OFFSET IO_BUF>, AX ,16 <OFFSET IO_BUF> 'H' BL, DSK_BUF BL, 0FCH M_3 FAT_SIZE, 2 CLST_SIZE, 1 M_11 BL, 0FDH M_4 FAT_SIZE, 2 CLST_SIZE, 2 M_11 BL, 0FEH M_5 FAT_SIZE, 1 CLST_SIZE, 1 M_11 BL, 0FFH M_6 FAT_SIZE, 1 CLST_SIZE, 2 M_11 BL, OFH0H M_7 FAT_SIZE, 9 CLST_SIZE, 1 M_11 BL, 0F9H M_8 INV_FAT: DSPLY_IMMED_STR <7, 'Unknown diskette format'> JMP DONE M_8: GET_PRMS BH,AL JNC M_9 MOV AL, 1 CMP AL, 3 JB M_10 MOV FAT_SIZE, 3 MOV CLST_SIZE, 2 JMP M_11 MOV FAT_SIZE, 7 MOV CLST_SIZE, 1 MOV CX, 4 MOV BL, FAT_SIZE READ_SCTR BH,0,0,2,BL,<OFFSET DSK_BUF>,AL JNC M_12 RESET_DISK BH LOOP LP_2 JMP READ_ERR MOV AL, FAT_SIZE MOV AH, 0 MOV BX, 512 MUL BX M_9: M_10: M_11: LP_2: M_12: 361 SHL MOV DIV AX, 1 BX, 3 BX MOV MOV MOV CMP JAE DX, AX AX, 2 CX, 0 AX,DX M_13 CALL CHECK_ENTRY INC AX JMP LP_3 MOV AX, CX MOV BL, CLST_SIZE MOV BH, 0 MUL BX LP_3: M_13: CNV_UNS_STR DSPLY_STR DSPLY_IMMED_STR DSPLY_IMMED_STR DONE: MAIN <OFFSET IO_BUF>,AX <OFFSET IO_BUF> 'bad or allocated sectors.' <13,10> RET ENDP ;----------------------------------------------------------------------CHECK_ENTRY CE_1: CE_2: CHECK_ENTRY CODE PROC PUSH PUSH PUSH MOV MUL SHR MOV MOV JC NEAR AX BX DX BX, 3 BX AX,1 BX, AX AX, WORD PTR [BX+DSK_BUF] CE_1 TEST AX, OFFFH JZ CE_2 INC CX JMP SHORT CE_2 TEST AX, OFFFOH JZ CE_2 INC CX POP DX POP BX POP AX RET ENDP ENDS END MAIN TITLE PROGRAM ASSIGNMENT 11-6 PAGE 55,80 COMMENT | PROGRAM : PA11-6.ASM PROGRAMMER : KADIR GECKIN 362 DATE : 24/12/2000 DISKET DIZIN LISTELEMESINI SAGLAYAN PROGRAM INPUT_STR, CNV_STR_UNS, CNV_UNS_STR, DSPLY_STR, DSPLY_IMMED_STR, READ_SCTR , RESET_DISK VE GET_PRMS YAPITASLARI KULLANILIR INPUT PARAMETERS : NONE OUTPUT PARAMETERS : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;STACK SEGMENT ======================================================== STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') STACK ENDS ;DATA SEGMENT ======================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DB 17 DUP('*') DSK_BUF DB 14 * 512 DUP ('#') SIDES SECTORS DIR_LOC DIR_SIZE INV_DRV DATA DB DB DB DB DB ENDS ? ? ? ? 7, ' Invalid drive - Try again',13,10,10,0 ;CODE SEGMENT ====================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:CODE MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX,DATA DS, AX DS:DATA GET_DRV: DRV_ERROR: M_1: DSPLY_IMMED_STR 'Drive number (0 -127)? ' INPUT_STR <OFFSET IO_BUF> CNV_STR_UNS <OFFSET IO_BUF>, AX MOV BH, AL JC DRV_ERROR CMP BH, 80H JB M_1 DSPLY_STR <OFFSET INV_DRV> JMP GET_DRV MOV CX, 4 READ_SCTR JNC M_2 RESET_DISK LOOP LP_1 BH,0,0,2,1,<OFFSET DSK_BUF>,AL BH 363 DSPLY_IMMED_STR <7, 'Unable to read FAT - '> DSPLY_IMMED_STR 'Status: ' CALL DSPLY_STAT JMP DONE M_2: M_3: M_4: M_5: M_7: INV_FAT: M_8: M_9: M_10: M_11: LP_2: MOV CMP JNE MOV MOV MOV MOV JMP CMP JNE MOV MOV MOV MOV JMP CMP JNE MOV MOV MOV MOV JMP CMP JNE MOV MOV MOV MOV JMP CMP JE BL, DSK_BUF BL, 0FCH M_3 SIDES, 1 SECTORS, 9 DIR_LOC, 5 DIR_SIZE, 4 M_11 BL, 0FDH M_4 SIDES, 2 SECTORS, 9 DIR_LOC, 5 DIR_SIZE, 7 M_11 BL, 0FEH M_5 SIDES, 1 SECTORS, 8 DIR_LOC, 3 DIR_SIZE, 4 M_11 BL, 0FFH M_6 SIDES, 2 SECTORS, 18 DIR_LOC, 19 DIR_SIZE, 14 M_11 BL, 0F9H M_8 DSPLY_IMMED_STR <7, 'Unknown diskette format'> JMP DONE GET_PRMS BH, AL JNC M_9 MOV AL, 1 CMP AL, 3 JB M_10 MOV SIDES, 2 MOV SECTORS, 9 MOV DIR_LOC, 7 MOV DIR_SIZE, 7 JMP M_11 MOV SIDES, 2 MOV SECTORS, 15 MOV DIR_LOC, 15 MOV DIR_SIZE, 14 MOV DI, OFFSET DSK_BUF MOV AL, DIR_LOC MOV CL, DIR_SIZE MOV CH, 0 CALL READ_LSCTR JC DONE INC AL ADD DI, 512 LOOP LP_2 364 LP_3: M_12: M_13: DONE: MAIN DSPLY_IMMED_STR <10, 'Directory entries:',13,10> MOV AL, DIR_SIZE MOV AH, 0 MOV CL, 4 SHL AX, CL MOV BX, 0 MOV CX, AX MOV SI, OFFSET DSK_BUF MOV AL, [SI] CMP AL, 0 JE M_13 CMP AL, 0E5H JE M_12 INC BX CALL DSPLY_ENTRY ADD SI, 32 LOOP LP_3 CNV_UNS_STR <OFFSET IO_BUF>,BX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <' files on diskette',13,10> RET ENDP ;-----------------------------------------------------------------------DSPLY_STAT PROC NEAR PUSH AX MOV AH,0 CNV_UNS_STR DSPLY_STR DSPLY_CHR POP AX RET DSPLY_STAT <OFFSET IO_BUF>,AX, 16 <OFFSET IO_BUF> 'H' ENDP ;-----------------------------------------------------------------------READ_LSCTR PROC NEAR PUSH PUSH PUSH PUSH AX BX CX DX MOV DIV INC MO MOV DIV MOV MOV MOV RL_LP: AH, 0 SECTORS AH DL, AH AH, 0 SIDES BL, AH DH, AL CX, 4 READ_SCTR BH,BL,DH,DL,1,DI,AL JNC RL_1 RESET_DISK BH LOOP RL_LP DSPLY_IMMED_STR <7, 'Unable to read FAT - '> DSPLY_IMMED_STR 'Status: ' CALL DSPLY_STAT STC 365 RL_1: REL_RET: READ_LSCTR JMP CLC POP POP POP POP RET ENDP SHORT RL_RET DX CX BX AX ;------------------------------------------------------------------------DSPLY_ENTRY PROC NEAR PUSH PUSH PUSH AX CX SI DSPLY_IMMED_STR ' ' MOV CX,11 LODSB DSPLY_CHR AL LOOP DE_LP1 DSPLY_IMMED_STR ' ' LODSB SHR AL,1 JNC DE_1 DSPLY_CHR 'R' SHR AL,1 JNC DE_2 DSPLY_CHR 'H' SHR AL,1 JNC DE_3 DSPLY_CHR 'S' SHR AL,1 DE_LP1: DE_1: DE_2: DE_3: JNC DE_4 DSPLY_CHR SHR AL,1 JNC DE_5 DSPLY_CHR SHR AL,1 JNC DE_6 DSPLY_CHR DSPLY_IMMED_STR POP SI POP CX POP AX RET DE_4: DE_5: DE_6: DSPLY_ENTRY CODE 'V' 'D' 'A' <13,10> ENDP ENDS END MAIN TITLE PROGRAM ASSIGNMENT 11-7 PAGE 55,80 COMMENT | PROGRAM : PA11-7.ASM PROGRAMMER : KADIR GECKIN DATE : 24/12/2000 366 KULLANIMDAKI BIR DOSYANIN MANTIKSAL KUMELERINI LISTELEYEN PROGRAM INPUT_STR, CNV_STR_UNS, CNV_UNS_STR, DSPLY_STR, DSPLY_IMMED_STR, READ_SCTR , RESET_DISK VE GET_PRMS YAPITASLARI KULLANILIR INPUT PARAMETERS : NONE OUTPUT PARAMETERS : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;STACK SEGMENT ======================================================== STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') STACK ENDS ;DATA SEGMENT ======================================================== DATA SEGMENT PARA PUBLIC 'DATA' FN_BUF DB 12 DUP('') IO_BUF DB 17 DUP('*') DSK_BUF DB 14 * 512 DUP ('#') SIDES SECTORS DIR_LOC DIR_SIZE FAT_SIZE STRT_CLST INV_DRV DATA DB DB DB DB DB DW DB ENDS ? ? ? ? ? ? 7, ' Invalid drive - Try again',13,10,10,0 ;CODE SEGMENT ====================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:CODE MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX,DATA DS, AX DS:DATA GET_DRV: DRV_ERROR: GET_MAME: DSPLY_IMMED_STR 'Drive number (0 -127)? ' INPUT_STR <OFFSET IO_BUF> CNV_STR_UNS <OFFSET IO_BUF>, AX MOV BH, AL JC DRV_ERROR CMP BH, 80H JB GET_NAME DSPLY_STR <OFFSET INV_DRV> JMP GET_DRV DSPLY_IMMED_STR 'Primary file name' DSPLY_IMMED_STR '(UPPER CASE ONLY)?' INPUT_STR <OFFSET FN_BUF>, 8, ' ' DSPLY_IMMED_STR 'File name extension' 367 M_1: DSPLY_IMMED_STR '(UPPER CASE ONLY)?' INPUT_STR <OFFSET FN_BUF+8>, 3, ' ' MOV CX, 4 READ_SCTR BH,0,0,2,1,<OFFSET DSK_BUF>,AL JNC M_2 RESET_DISK BH LOOP LP_1 DSPLY_IMMED_STR <7, 'Unable to read FAT - '> DSPLY_IMMED_STR 'Status: ' CALL DSPLY_STAT JMP DONE M_2: MOV CMP JNE MOV MOV MOV MOV MOV JMP BL, DSK_BUF BL, 0FCH M_3 SIDES, 1 SECTORS, 9 DIR_LOC, 5 DIR_SIZE, 4 FAT_SIZE, 2 M_11 M_3: CMP JNE MOV MOV MOV MOV MOV JMP BL, 0FDH M_4 SIDES, 2 SECTORS, 9 DIR_LOC, 5 DIR_SIZE, 7 FAT_SIZE, 2 M_11 M_4: CMP JNE MOV MOV MOV MOV MOV JMP BL, 0FEH M_5 SIDES, 2 SECTORS, 8 DIR_LOC, 3 DIR_SIZE, 4 FAT_SIZE, 1 M_11 M_5: CMP JNE MOV MOV MOV MOV MOV JMP BL, 0FFH M_6 SIDES, 2 SECTORS, 8 DIR_LOC, 3 DIR_SIZE, 7 FAT_SIZE, 1 M_11 M_6: CMP JNE MOV MOV MOV MOV MOV JMP CMP JE BL, 0F0H M_7 SIDES, 2 SECTORS, 18 DIR_LOC, 19 DIR_SIZE, 14 FAT_SIZE, 9 M_11 BL, 0F9H M_8 M_7: INV_FAT DSPLY_IMMED_STR <7, 'Unknown diskette format'> JMP DONE 368 M_8: M_9: GET_PRMS BH, AL JNC M_9 MOV AL, 1 CMP AL, 3 JB M_10 MOV SIDES, 2 MOV SECTORS, 9 MOV DIR_LOC, 7 MOV DIR_SIZE, 7 MOV FAT_SIZE, 3 JMP M_11 M_10: MOV MOV MOV MOV MOV SIDES, 2 SECTORS, 15 DIR_LOC, 15 DIR_SIZE, 14 FAT_SIZE, 7 M_11: MOV MOV MOV MOV DI, AL, CL, CH, LP_2: CALL READ_LSCTR JNC M_11A JMP DONE INC AL ADD DI,512 LOOP LP_2 M_11A: MOV MOV MOV SHL MOV MOV LP_3: CMP JE M_12: NOT_FOUND: M_13: M_14: LP_4: M_14A: OFFSET DSK_BUF DIR_LOC DIR_SIZE 0 AL, DIR_SIZE AH, 0 CL, 4 AH, CL CX, AX SI, OFFSET DSK_BUF MOV AL, [SI] AL, 0 NOT_FOUND CMP AL,0E5H JE M_12 CALL CHECK_ENTRY JZ M_13 ADD SI, 32 LOOP LP_3 DSPLY_IMMED_STR <7, 'File not found', 13, 10> JMP DONE MOV AX, [SI+26] CMP AX, 0 JA M_14 DSPLY_IMMED_STR <'No clusters allocated',13,10> JMP DONE MOV STRT_CLST, AX MOV DI, OFFSET DSK_BUF MOV AL, 1 MOV CL, FAT_SIZE MOV CH, 0 CALL READ_LSCTR JNC M_14A JMP DONE INC AX 369 LOOP LP_5: ADD DI, 512 LP_4 DSPLY_IMMED_STR <10, 'Logical cluster:',13,10> MOV AX, STRT_CLST MOV CX,0 INC CX CNV_UNS_STR <OFFSET IO_BUF>, AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR ' ' CALL GET_NXT_LCN CMP AX, OFF8H JB LP_5 DSPLY_IMMED_STR <13, 10, 10> CN_UNS_STR <OFFSET IO_BUF>,CX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR<' cluster in file', 13, 10> DONE: MAIN RET ENDP ;------------------------------------------------------------------------DSPLY_STAT PROC NEAR PUSH AX MOV AH, 0 CNV_UNS_STR DSPLY_STR DSPLY_CHR POP AX RET DSPLY_STAT <OFFSET IO_BUF>,AX,16 <OFFSET IO_BUF> 'H' ENDP ;-----------------------------------------------------------------------DSPLY_STAT PROC NEAR PUSH AX MOV AH, 0 CNV_UNS_STR DSPLY_STR DSPLY_CHR POP AX RET DSPLY_STAT <OFFSET IO_BUF>,AX, 16 <OFFSET IO_BUF> 'H' ENDP ;------------------------------------------------------------------------READ_LSCTR PROC NEAR PUSH PUSH PUSH PUSH MOV DIV INC MOV MOV AX BX CX DX AH, 0 SECTORS AH DL, AH AH, 0 370 DIV MOV MOV MOV JNC RL_1: RL_RET: READ_LSCTR SIDES BL, AH DH, AL CX, 4 RL_1 RESET_DISK LOOP RL_LP DSPLY_IMMED_STR<7, 'Unable to read FAT - '> DSPLY_IMMED_STR 'Status: ' CALL DSPLY_STAT STC JMP SHORT RL_RET CLC POP DX POP CX POP BX POP AX RET ENDP ;-----------------------------------------------------------------------CHECK_ENTRY CHECK_ENTRY PROC NEAR PUSH PUSH PUSH PUSH PUSH MOV PUSH POP AX CX SI DI ES DI, OFFSET FN_BUF DS ES CLD MOV REPE POP POP POP POP POP RET ENDP CX, 11 CMPSB ES DI SI CX AX ;---------------------------------------------------------------------GET_NXT_LCN PROC NEAR PUSH PUSH PUSH MOV MUL SHR BX CX DX BX, 3 BX AX, 1 MOV MOV JC GNL_1: BX, AX AX, WORD PTR [BX+DSK_BUF] GNL_1 AND AX, 0FFFH JMP MOV SHORT GNL_2 CL, 4 371 GNL_2: POP POP POP RET GET_NXT_LCN CODE ENDP ENDS END SHR DX CX BX AX, CL MAIN TITLE PROGRAM ASSIGNMENT 11-8 PAGE 55,80 COMMENT | PROGRAM : PA11-8.ASM PROGRAMMER : KADIR GECKIN DATE : 24/12/2000 DISKI SEKTOR SEKTOR DOGRULAR INPUT_STR, CNV_STR_UNS, CNV_UNS_STR, DSPLY_STR, DSPLY_IMMED_STR, READ_SCTR, VERIFY_SCTR, RESET_DISK VE GET_PRMS YAPITASLARI KULLANILIR INPUT PARAMETERS : NONE OUTPUT PARAMETERS : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;STACK SEGMENT ======================================================== STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') STACK ENDS ;DATA SEGMENT ======================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DSK_BUF DB DB 17 DUP('*') 512 DUP ('#') SIDES TRACKS SECTORS BAD_SCTRS INV_DRV DATA DW DW DW DW DB ENDS ? ? ? ? 7, ' Invalid drive - Try again',13,10,10,0 ;CODE SEGMENT ====================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:CODE MAIN PROC FAR PUSH DS 372 MOV PUSH MOV MOV ASSUME GET_DRV: GD_INV: DRV_TYPE: DT_1: FLOPPY: F_1: GET_FAT: FAT_LP: GF_1: DSKT_PRMS: GF_1: DSKT_PRMS: AX, 0 AX AX,DATA DS, AX DS:DATA DSPLY_IMMED_STR 'Drive number (0 -127 ' DSPLY_IMMED_STR '= floppy, 128 -255 = hard)? ' INPUT_STR <OFFSET IO_BUF> CNV_STR_UNS <OFFSET IO_BUF>, BX JC GD_INV TEST BH, BH JC DRV_TYPE DSPLY_STR <OFFSET INV_DRV> JMP GET_DRV CMP BL, 80H JB FLOPPY GET_PRMS BL, , AL, CX, DL, , DH JNC DT_1 DSPLY_IMMED_STR <7, 'Cannot determine drive '> DSPLY_IMMED_STR 'parameters' MOV AL, DH CALL DSPLY_STAT JMP M_RET SUB AH, AH MOV SIDES, AX MOV TRACKS, CX XOR DH, DH MOV SECTORS, DX JMP VRFY_DISK GET_PRMS BL, BH, , , , , , AL JNC GET_FAT CMP AL, 1 JE F_1 DSPLY_IMMED_STR <7, 'Cannot determine drive '> DSPLY_IMMED_STR 'parameters' CALL DSPLY_STAT JMP M_RET MOV BH, 1 MOV CX, 4 READ_SCTR BL,0,0,2,1,<OFFSET DSK_BUF>,AL JNC GF_1 RESET_DISK BL LOOP FAT_LP DSPLY_IMMED_STR <7, 'Unable to read diskette FAT'> CALL DSPLY_STAT JMP M_RET MOV DH, DSK_BUF MOV MOV CMP JNE MOV JMP MOV SIDES, 1 TRACKS, 40 DH, 0FCH GP_1 SECTORS, 9 SHORT VRFY_DISK DH, DSK_BUF MOV MOV CMP JNE SIDES, 1 TRACK, 40 DH, 0FCH GP_1 373 MOV JMP SECTORS, 9 SHORT VRFY_DISK GP_1: CMP JNE MOV JMP DH, 0FCH GP_2 SECTORS, 8 SHORT VRFY_DISK GP_2: MOV CMP JNE MOV JMP SIDES, 2 DH, 0FDH GP_3 SECTORS, 9 SHORT VRFY_DISK GP_3: CMP JNE MOV JMP DH, 0FFH GP_4 SECTORS, 8 SHORT VRFY_DISK GP_1: MOV CMP JNE MOV JMP TRACKS, 80 DH, 0F0H GP_5 SECTORS, 18 SHORT VRFY_DISK GP_5: CMP JE DH, 0F9H GP_6 INV_FAT: DSPLY_IMMED_STR <7, 'Unknown diskette CALL DSPLY_FMT JMP M_RET GP_6: CMP JB MOV JMP BH, 3 GP_7 SECTORS, 9 SHORT VRFY_DISK GP_7: MOV SECTORS, 15 VRFY_DISK: DSPLY_IMMED_STR <13,10, 'Verifying the disk: '> MOV AX, SIDES CNV_UNS_STR <OFFSET IO_BUF>,AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR ' side(s), ' MOV AX,TRACKS CNV_UNS_STR <OFFSET IO_BUF>, AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <' sectors per track.', 13, 10> DSPLY_IMMED_STR <'. = 1 cylinder verified.',13,10> MOV DL, 0 MOV CX, TRACKS VRFY_LP: CALL VRFY_CYL INC DL LOOP VRFY_LP DSPLY_IMMED_STR <13, 10, 'Verify complete - '> MOV AX, BAD_SCTRS CNV_UNS_STR <OFFSET IO_BUF>, AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <' bad sectors.',13, 10> M_RET: MAIN RET ENDP 374 format'> ;------------------------------------------------------------------------VRFY_CYL PROC NEAR PUSH CX DSPLY_CHR '.' MOV DH, 0 MOV CX, SIDES CYL_LP: VRFY: CALL VRFY_TRAK INC DH LOOP CYL_LP POP CX RET ENDP ;------------------------------------------------------------------------VRFY_TRAK PROC NEAR PUSH MOV MOV TRAK_LOOP: VRFY_TRAK CX BH, 1 CX, SECTORS CALL VRFY_SCTR INC BH LOOP TRAK_LOOP POP CX RET ENDP ;-------------------------------------------------------------------------VRFY_SCTR VS_LP: VS_1: VS_ERR: VS_RET: VRFY_SCTR PROC NEAR PUSH AX PUSH CX MOV CX, 4 VERIFY_SCTR BL, DH, BH, 1, AL JC VS_1 JMP VS_RET RESET_DISK BL LOOP VS_LP SUB AH, AH DSPLY_IMMED_STR <13, 103 'Side '> MOV AL, DH CNV_UNS_STR <OFFSET IO_BUF>, AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR ', Track' MOV AL,DL CNV_UNS_STR <OFFSET IO_BUF>, AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR ', Sector' MOV AL, BH CNV_UNS_STR <OFFSET IO_BUF>, AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <'- BAD', 13, 10> INC BAD_SCTRS POP POP RET ENDP CX AX 375 ;------------------------------------------------------------------------DSPLY_STAT PROC NEAR PUSH AX DSPLY_IMMED_STR ' - Status:' MOV AL, DH CNV_UNS_STR <OFFSET IO_BUF>, AX, 16 DSPLY_STR <OFFSET IO_BUF> DSPLY_CHR 'H' POP AX DSPLY_STAT ENDP ;-------------------------------------------------------------------------DSPLY_FMT PROC NEAR PUSH AX DSPLY_IMMED_STR ': ' SUB AH, AH MOV AL, DH CNV_UNS_STR <OFFSET IO_BUF>, AX, 16 DSPLY_STR <OFFSET IO_BUF> DSPLY_CHR 'H' POP AX RET DSPLY_FMT CODE ENDP ENDS END MAIN 376 ASSEMBLY PROGRAM ÖRNEKLERİ BÖLÜM-7: COMMENT | SEL_DEF MACRO ================================================= VARSAYILANB DISK SURUCUSUNU SECER. ZATEN (SECIMLIK) MANTIKSAL DISK SURUCUSUNUN NUMARALARI GERI DONER. DISK.LIB ICINDE $SEL_DEF PROSEDURU KULLANILIR. INPUT PARAMTERS: DEF_DRV: DEFAULT DRIVE BYTE REGISTER OR IMMEDIATE 0 = A, 1 = B, 2 = C, ETC. DEFAULTS TO 0 (A) OUTPUT PARAMTERS: NO_DRVS = NUMBER OF LOGICAL DRIVES BYTE REGISTER OPTIONAL | SEL_DEF MACRO DEF_DRV, NO_DRVS IFNDEF $SEL_DEF EXTRN $SEL_DEF:NEAR ENDIF PUSH BP DEC SP MOV BP, SP IFB <DEF_DRV> MOV BYTE PTR [BP], 0 ELSE MOV BYTE PTR [BP], DEF_DRV ENDIF CALL $SEL_DEF IFNB <NO_DRVS> MOV NO_DRVS, BYTE PTR [BP] ENDIF INC SP POP BP ENDM COMMENT | GET_DEF MACRO ================================================ GECERLI VARSAYILAN DISK SURUCUSUNU BULUR. DISK.LIB ICINDE $GET_DEF PROSEDURU KULLANILIR. INPUT PARAMETERS: NONE OUTPUT PARAMETERS: DEF_DRV = DEFAULT DRIVE BYTE REGISTER 0 = A, 1 = B, 2 = C, ETC | GET_DEF MACRO DEF_DRV IFNDEF $GET_DEF EXTRN $GET_DEF ENDIF 377 PUSH DEC MOV CALL MOV INC POP ENDM BP SP BP, SP $GET_DEF DEF_DRV, [BP] SP BP COMMENT | SET_DTA MACRO ================================================== SIRALI DISK ERISIMI ICIN DISKIN AKTARIM ADRESLERINI AYARLAR DISK.LIB ICINDE $SET_DTA PROSEDURU KULLANILIR. INPUT PARAMETERS: DTA_OFF = OFFSET OF DISK TRANSFER AREA IN DATA SEGMENT WORD REGISTER OR IMMEDIATE OUTPUT PARAMETERS: NONE | SET_DAT MACRO DTA_OFF IFNDEF $SET_DTA EXTRN $SET_DTA:NEAR ENDIF COMMENT | PUSH DEC DEC MOV MOV CALL BP SP SP BP, SP WORD PTR [BP], DTA_OFF $SET_DTA POP ENDM BP GET_DTA MACRO ============================================= DISKIN AKTARIM ADRESLERINI ELDE EDER DISK.LIB ICINDE $GET_DTA PROSEDURU KULLANILIR. IN: NONE OUT: DTA_OFF = OFFSET OF DISK TRANSFER AREA WORD REGISTER DTA_SEG = SEGMENT OF DISK TRANSFER AREA WORD REGISTER | GET_DTA MACRO DTA_OFF, DTA_SEG IFNDEF $GET_DTA EXTRN $GET_DTA:NEAR ENDIF PUSH SUB BP SP, 4 MOV CALL BP,SP $GET_DTA IFNB <DTA_OFF> 378 MOV DTA_OFF, WORD PTR [BP] ENDIF IFNB <DTA_SEG> MOV DTA_SEG, WORD PTR [BP+2] ENDIF ADD SP, 4 POP BP ENDM COMMENT | GET_DSK_SPACE MACRO ======================================== DISKIN TABLOLAMA BILGISINI ELDE EDER DISK.LIB ICINDE $GET_DS_SPACE PROSEDURU KULLANILIR. INPUT PARAMETERS: DRV = DRIVE TO GET INFO FOR BYTE REGISTER OR IMMEDIATE 0 = DEFAULT, 1 = A, 2 = B, ETC. DEFAULT TO 0 (DEFAULT DRIVE) OUTPUT PARAMETERS: FRE_CL = NUMBER OF UNALLOCATED CLUSTER ON DISK WORD REGISTER OPTIONAL TTL_CL = TOTAL NUMBER OF CLUSTER ON DISK WORD REGISTER OPTIONAL CL_SIZ = SIZE OF EACH CLUSTER (NUMBER OF SECTORS) WORD REGISTER OPTIONAL FFFFH = DRIVE WAS INVALID SCT_SIZ = SIZE OF EACH SECTOR (NUMBER OF BYTES) WORD REGSISTER OPTIONAL RETURN FFFFH IN CL_SIZ IF DRIVE IS INVALID NO OTHER ERROR RETURNED | GET_DSK_SPACE MACRO DRV, FRE_CL, TTL_CL, CL_SIZ, SCT_SIZ IFNDEF $GET_DSK_SPACE EXTRN $GET_DSK_SPACE:NEAR ENDIF PUSH SUB MOV IFB BP SP, 8 BP, SP <DRV> MOV BYTE PTR [BP], 0 ELSE MOV BYTE PTR [BP], DRV ENDIF CALL $GET_DSK_SPACE IFNB <FRE_CL> MOV FRE_CL, WORD PTR [BP+0] ENDIF IFNB <TTL_CL> MOV TTL_CL, WORD PTR [BP+2] ENDIF IFNB <CL_SIZ> MOV SCT_SIZ, WORD PTR [BP+4] 379 ENDIF IFNB <SCT_SIZ> MOV SCT_SIZ, WORD PTR [BP+6] ENDIF ADD SP, 8 POP BP ENDM COMMENT | CNV_STRL_ASCZ MACRO ========================================== BYTE UZUNLUGUNDA BIR STRINGI ASCIIZ SITRINGINE (BOS KUYRUK) CEVIRIR. DISK.LIB ICINDE $CNV_STRL_ASCZ PROSEDURU KULLANILIR. INPUT PARAMETERS: STR_OFF = OFFSET OF STRING TO BE CONVERTED WORD REGISTER OR IMMEDIATE OUTPUT PARAMETERS: NONE | CNV_STRL_ASCZ MACRO STR_OFF IFNDEF $CNV_STRL_ASCZ EXTRN $CNV_STRL_ASCZ ENDIF PUSH DEC DEC MOV MOV CALL POP ENDM COMMENT | BP SP SP BP, SP WORD PTR [BP], STR_OFF $CNV_STRL_ASCZ BP MKDIR MACRO =================================================== ALTDIZIN YARATIR. DISK.LIB ICINDE $MKDIR PROSEDURU KULLANILIR. INPUT PARAMETERS: ASCZ_OFF = OFFSET OF ASCIIZ DRIVE AND PATH WORD REGISTER OR IMMEDIATE OUTPUT PARAMTERS: ERROR = ERROR CODE RETURNED BY DOS BYTE REGISTER OPTIONAL MEANINGFUL ONLY IF CARRY FLAG SET POSSIBLE ERROR CODES ARE AS FOLLOWS: 01H Invalid function number 02H File not found. 03H Path not found. 04H Too many open files 05H Access denied. 06H Invalid handle. 07H Memory control block. destroyed 08H Insufficient memory. 09H Invalid memory block address. 0AH Invalid environment. 0BH Invalid format. 10H Attempted renoval of current directory 11H Not same device. 12H No more files. 13H Disk write protected. 14H Unknown unit. 15H Drive not ready. 16H Unknown command. 17H Data error (bad CRC) 18H Bad request structure length. 19H Seek error. 1AH Unknown media type. 1BH Sector not found. 380 0CH 0DH 0EH 0FH Invalid Invalid Unknown Invalid CARRY access code. Data unit. drive. 1CH 1DH 1EH 1FH Printer out of paper. Write fault. Read fault. General failure. FLAG SET IF ERROR | MKDIR MACRO ASCZ_OFF, ERROR IFNDEF $MKDIR EXTRN $MKDIR:NEAR ENDIF PUSH BP DEC SP DEC SP MOV BP, SP MOV WORD PTR [BP], ASCZ_OFF CALL $MKDIR IFNB <ERROR> MOV ERROR, BYTE PTR [BP+1] ENDIF INC SP POP BP ENDM COMMENT | RMDIR MACRO ================================================ ALTDIZIN SILER DISK.LIB ICINDE $RMDIR PROSEDURU KULLANILIR. INPUT PARAMETERS: ASCZ_OFF = OFFSET OF ASCIIZ DRIVE AND PATH WORD REGISTERS OR IMMEDIATE OUTPUT PARAMTERS: ERROR = ERROR CODE RETURNED BY DOS BYTE REGISTER OPTIONAL MEANINGFUL ONLY IF CARRY FLAG SET SEE MKDIR FOR POSSIBLE ERROR CODES CARRY FLAG SET IF ERROR | RMDIR MACRO ASCZ_OFF, ERROR IFNDEF $RMDIR:NEAR ENDIF PUSH DEC DEC MOV MOV CALL IFNB BP SP SP BP,SP WORD PTR [BP], ASCZ_OFF $RMDIR <ERROR> MOV ERROR, BYTE PTR [BP+1] ENDIF INC SP POP BP ENDM COMMENT | CHDIR MACRO ================================================= GUNCEL DIZINI DEGISTIRIR. DISK.LIB ICINDE $CHDIR PROSEDURU KULLANILIR. 381 INPUT PARAMETERS: ASCZ_OFF = OFFSET OF ASCIIZ DRIVE AND PATH WORD REGISTER OR IMMEDIATE OUTPUT PARAMTERS: ERROR = ERROR CODE RETURNED BY DOS BYTE REGISTER OPTIONAL MEANINGFUL ONLY IF CARRY FLAG SET SEE MKDIR FOR POSSIBLE ERROR CODES CARRY FLAG SET IF ERROR | CHDIR MACRO ASCZ_OFF, ERROR IFNDEF $CHDIR EXTRN $CHDIR:NEAR ENDIF PUSH BP DEC SP DEC SP MOV BP,SP MOV WORD PTR [BP], ASCZ_OFF CALL $CHDIR IFNB <ERROR> MOV ERROR, BYTE PTR [BP+1] ENDIF INC SP POP BP ENDM COMMENT | GET_DIR MACRO ============================================ GUNCEL ALTDIZINI ELDE EDER DISK.LIB ICINDE $GET_DIR PROSEDURU KULLANILIR. INPUT PARAMTERS: DRV = DRIVE TO GET CURNENT DIRECTORY FOR BYTE REGISTER OR IMMEDIATE 0 = DEFAULT, 1 = A, 2 = B, ETC. DEFAULTS TO 0 (DEFAULT DRIVE) BUFF_OFF = OFFSET OF BUFFER TO RECEIVE ASCIIZ DRIVE AND PATH WORD REGISTER OR IMMEDIATE OUTPUT PARAMTERS: ERROR = ERROR CODE RETURNED BY DOS BYTE REGISTER OPTIONAL MENINGFUL ONLY IF CARRY FLAG SET SEE MKDIR FOR POSSIBLE ERROR CODES CARRY FLAG SET IF ERROR | GET_DIR MACRO DRV, BUFF_OFF, ERROR IFNDEF $GET_DIR EXTRN $GET_DIR: NEAR EDNIF PUSH BP SUB SP, 3 MOV BP, SP IFB <DRV> MOV BYTE PTR [BP], 0 382 ELSE MOV BYTE PTR [BP], DRV ENDIF MOV WORD PTR [BP+1], BUFF_OFF CALL $GET_DIR IFNB <ERROR> MOV ERROR, BYTE PTR [BP+2] ENDIF INC SP POP BP ENDM COMMENT | CHG_ATT MACRO ================================================ BIR DOSYANIN OZELLIK BYTE'INI DEGISTIRIR. DISK.LIB ICINDE $CHG_ATT PROSEDURU KULLANILIR. INPUT PARAMMETERS: ASCZ_OFF = OFFSET OF ASCIIZ DRIVE AND PATH WORD REGISTER OR IMMEDIATE ATT = ATTRIBUTE BYTE OF THE FILE BYTE REGISTER MEANINGS OF BITS SHOW BELOW OUTPUT PARAMETERS: ERROR = ERROR CODE RETURNED BY DOS BYTE REGISTER OPTIONAL MEANINGFUL ONLY IF CARRY FLAG SET SEE MKDIR FOR POSSIBLE ERROR CODES CARRY FLAG SET IF ERROR MEANING OF ATT BYTE IS AS FOLLWS: BIT MEANING_IF SET 0 1 2 3 4 5 6 - 7 READ_ONLY FILE HIDDEN FILE. SYSTEM FILE. VOLUME LABEL. SUB - DIRECTORY FILE FILE MODIFIED SINCE LAST BACK-UP (ARCHIVE BIT). UNUSED. | CHG_ATT MACRO IFNDEF ENDIF PUSH SUB MOV MOV IFB ASCZ_OFF, ATT, ERROR $CHG_ATT:NEAR BP SP, 3 BP, SP WORD PTR [BP], ASCZ_OFF <ATT> MOV BYTE PTR [BP+2], 0 ELSE MOV BYTE PTR [BP+2], ATT ENDIF CALL $CHG_ATT IFNB <ERROR> MOV ERROR, BYTE PTR [BP+2] ENDIF INC SP 383 POP ENDM BP COMMENT | GET_ATT MACRO ================================================= BIR DOSYANIN OZELLIK BYTE'INI ELDE EDER DISK.LIB ICINDE $GET_ATT PROSEDURU KULLANILIR. INPUT PARAMETERS: ASCZ_OFF = OFFSET OF ASCIIZ DRIVE AND PATH WORD REGISTER OR IMMEDIATE OUTPUT PARAMTERS: ATT = ATTRIBUTE BYTE OF THE FILE BYTE REGISTER SEE CHG_ATT FOR MEANING OF BITS ERROR = ERROR CODE RETURNED BY DOS BYTE REGISTER OPTIONAL MEANINGFUL ONLY IF CARRY FLAG SET SEE MKDIR FOR POSSIBLE ERROR CODES CARRY FLAG SET IF ERROR | GET_ATT MACRO ASCZ_OFF, ATT, ERROR IFNDEF $GET_ATT EXTRN $GET_ATT:NEAR ENDIF PUSH BP DEC SP DEC SP MOV BP, SP MOV WORD PTR [BP], ASCZ_OFF CALL $GET_ATT MOV ATT, BYTE PTR [BP+0] IFNB <ERROR> MOV ERROR, BYTE PTR [BP+1] ENDIF INC SP INC SP POP BP ENDM COMMENT | DEL_FILE MACRO ================================================== BIR DOSYA SILER DISK.LIB ICINDE $DEL_FILE PROSEDURU KULLANILIR. INPUT PARAMETERS: ASCZ_OFF = OFFSET OF ASCIIZ DRIVE AND PATH WORD REGISTER OPTIONAL MEANINGFUL ONLY IF CARRY FLAG SET SEE MKDIR FOR POSSIBLE ERROR CODES CARRY FLAG SET IF ERROR | DEL_FILE MACRO ASCZ_OFF, ERROR IFNDEF $DEL_FILE EXTRN $DEL_FILE:NEAR ENDIF PUSH DEC BP SP 384 DEC SP MOV BP, SP MOV WORD PTR [BP], ASCZ_OFF CALL $DEL_FILE MOV ATT, BYTE PTR [BP+0] IFNB <ERROR> MOV ERROR, BYTE PTR [BP+1] ENDIF INC SP POP BP ENDM COMMENT | REN_FILE MACRO ================================================== BIR DOSYA ISMI DEGISTIRIR DISK.LIB ICINDE $REN_FILE PROSEDURU KULLANILIR. INPUT PARAMTERS: OLDASCZ_OFF = OFFSET OF ASCIIZ DRIVE AND PATH OF FILE TO RENAME WORD REGISTER OR IMMEDIATE OFFSET OF ASCIIZ DRIVE AND PATH OF NEW FILE NAME WORD REGISTER OR IMMEDIATE OUTPUT PARAMTERS: ERROR = ERROR CODE RETURNED BY DOS BYTE REGISTER OPTIONAL MEANINGFUL ONLY IF CARRY FLAG SET SEE MKDIR FOR POSSIBLE ERROR CODES CARRY FLAG SET IF ERROR | REN_FILE MACRO OLDASCZ_OFF, NEWASCZ_OFF, ERROR IFNDEF $REN_FILE EXTRN $REN_FILE:NEAR ENDIF PUSH SUB BP SP, 4 MOV MOV MOV BP, SP WORD PTR [BP+0], OLDASCZ_OFF WORD PTR [BP+2], NEWASCZ_OFF CALL $REN_FILE IFNB <ERROR> MOV ERROR, BYTE PTR [BP+3] ENDIF INC SP POP BP ENDM COMMENT | DEFINE_DIR_BFR_STRUCT MACRO ARAMA TAMPONUNDA BIR DIZIN TANIMLAR DIR_BUFFER YAPISI TANIMLANIR INVOKE AT THE BEGINING OF ANY FILE WHICH NEEDS A DIRECTORY SEARCH BUFFER: DEFINE_DIR_BFR_STRUCT ONCE THE STRUCTURE HAS BEEN DEFINED, ALLOCATE A DIRECTORY 385 SEARH BUFFER WITHIN THE DATA SEGMENT OF THE FILE: FNAME_BUF DIR_BUFFER <> ONCE A BUFFER STRUCTURE HAS BEEN ALLACATED WITHIN TEH DATA SEGMENT, THE CODE MAY ADDRESS THE FIELDS AS FOLLOWS: MOV AL, FNAME_BUF.ATT MOV BX, FNAME_BUF.D_DATE DSPLY_STR <OFFSET FNAME_BUF.ASCIIZ> INPUT PARAMETERS: NONE OUTPUT PARAMETERS: NONE | DEFINE_DIR_BFR_STRUCT DIR_BUFFER ATT D_TIME D_DATE D_SIZE_L D_SIZE_M ASCIIZ DIR_BUFFER COMMENT | MACRO STRUC DB DB DB DB DB DB DB 21 DUP (?) ? ? ? ? ? 13 DUP(?) ENDS ENDM DIR_FRST MACRO ============================================ BIRINCI ESLEME ICIN DISIN GIRISINI ARAR DISK.LIB ICINDE $DIR_FIRST PROSEDURU KULLANILIR. * * * * * * * * * I M P O R T A N T * * * * * * * * * * * BEFORE INVOKING DIR_FRST USE SET_DTA TO SET THE DISK-TRANSFER ADDRESS TO A 43-BYTE DIRECTORY SEARCH BUFFER TO RECEIVE MATCHING FILENAME INFORMATION (SEE DEFINE_DIR_BFR_STRUCT ABOVE) * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * INPUT PARAMETERS: ASCZ_OFF = OFFSET OF ASCIIZ DRIVE, PATH AND FILENAME AND EXTENSION (MAY CONTAIN WILDCARDS - SEE DIR_NXT BELOW) WORD REGISTER OR IMMEDIATE ATT = ATTRIBUTE BYTE TO USE IN SEARCH BYTE REGISTER DEFAULTS TO 0 (NORMAL) SEE CHG_ATT AND BELOW FOR MEANING OF BITS OUTPUT PARAMTERS: ERROR = ERROR CODE RETURNED BY DOS BYTE REGISTER OPTIONAL MEANINGFUL ONLY IF CARRY FLAG SET SEE MKDIR FOR POSSIBLE ERROR CODES CARRY FLAG SET IF ERROR ATT BITS: IF VOLUME-LABEL BIT (#3) IS SET, ONLY VOLUME LABEL WILL BE FOUND. ANY OTHER BIT(S) SET CAUSES SEARCH TO FIND THE APPROPRIATE TYPE(S) OF ENTRIES IN ADDITON TO NORMAL FILES. 386 | DIR_FRST MACRO ASCZ_OFF, ATT, ERROR IFNDEF $DIR_FRST EXTRN $DIR_FRST:NEAR ENDIF PUSH BP SUB SP, 3 MOV BP, SP MOV WORD PTR [BP], ASCZ_OFF IFB <ATT> MOV BYTE PTR [BP+2], 0 ELSE MOV BYTE PTR [BP+2], ATT ENDIF CALL $DIR_FRST IFNB <ERROR> MOV ERROR, BYTE PTR [BP+2] ENDIF INC SP POP BP ENDM COMMENT | DIR_NXT MACRO ================================================ DIZIN ARASTIRMASINA DEVAM EDER DISK.LIB ICINDE $DIR_NEXT PROSEDURU KULLANILIR. * * * * * * * * * I M P O R T A N T * * * * * * * * * * * BEFORE INVOKING DIR_FRST USE SET_DTA TO SET THE DISK-TRANSFER ADDRESS TO A 43-BYTE DIRECTORY SEARCH BUFFER TO RECEIVE MATCHING FILENAME INFORMATION (SEE DEFINE_DIR_BFR_STRUCT ABOVE) THEN INVOKE DIR_FIRST TO BEGIN THE SEARCH - DO NOT CHANGE THE DTA WHILE CONTINUING A SEARCH * * * * * * * * * * * * * * * * * * ** * * * * * * * * * * INPUT PARAMETERS: NONE OUTPUT PARAMTERS: ERROR = ERROR CODE RETURNED BY DOS BYTE REGISTER OPTIONAL MEANINGFUL ONLY IF CARRY FLAG SET SEE MKDIR FOR POSSIBLE ERROR CODES CARRY FLAG SET IF ERROR | DIR_FRST MACRO ERROR IFNDEF $DIR_NXT EXTRN $DIR_NXT:NEAR ENDIF PUSH DEC MOV CALL BP SP BP, SP $DIR_FRST IFNB <ERROR> MOV ERROR, BYTE PTR [BP+0] ENDIF INC SP POP BP 387 ENDM COMMENT | OPEN_FILE MACRO ================================================== VAROLAN BIR DOSYA ACAR DISK.LIB ICINDE $OPEN_FILE PROSEDURU KULLANILIR. INPUT PARAMETERS: ASCZ_OFF = OFFSET ASCIIZ FILE SPECIFICATION WORD REGISTER OR IMMEDIATE MODE = ACCESS MODE FOR FILE: BYTE REGISTER OR IMMEDIATE DEFAULT = 2 (READ/WRITE) IMMEDIATE: R OR 0 = READ ONLY W OR 1 = WRITE ONLY R/W OR 2 = READ/WRITE REGISTER: 0 = READ ONLY 1 = WRITE ONLY 2 = READ/WRITE OUTPUT PARAMETERS: HANDLE = FILE HANDLE RETURNED BY DOS WORD REGISTER ERROR = ERROR RETURNED BY DOS BYTE REGISTER (OPTIONAL) MEANINGFUL ONLY IF CARRY FLAG SET CARRY FLAG CLEARED IF SUCCESSFUL, SET IF ERROR | OPEN_FILE MACRO ASCZ_OFF, MODE, HANDLE, ERROR IFNDEF $OPEN_FILE EXTRN $OPEN_FILE:NEAR ENDIF PUSH BP SUB SP, 3 MOV BP, SP MOV WORD PTR [BP], ASCZ_OFF IFB <MODE> MOV BYTE PTR [BP+2], 2 ELSE IFIDN <MODE>, <W> MOV BYTE PTR [BP+2], 1; W=1 (WRITE ONLY) ELSE IFNIDN <MODE>,<R/W> MOV BYTE PTR [BP+2], 2 ELSE MOV BYTE PTR [BP+2], MODE ENDIF ENDIF ENDIF ENDIF CALL $OPEN_FILE MOV HANDLE, WORD PTR [BP+0] IFNB <ERROR> MOV ERROR, BYTE PTR [BP+2] ENDIF INC SP INC SP INC SP 388 POP BP ENDM COMMENT | CREATE FILE MACRO ============================================== YENI DOSYA YARATIR. DISK.LIB ICINDE $CREATE_FILE PROSEDURU KULLANILIR. INPUT PARAMETERS: ASCZ_OFF = OFFSET OF ASCIIZ STRING WITHIN THE DATA SEGMENT WORD REGISTER OR IMMEDIATE ATT = ATTRIBUTE BYTE FOR FILE BYTE REGISTER OR IMMEDIATE DEFAULT = 0 (NORMAL FILE) SEE CHG_ATT FOR MEANINGS OF BITS OUTPUT PARAMTERS: HADNLE = FILE HANDLE RETURNED BY DOS WORD REGISTER ERROR = ERROR RETURNED BY DOS BYTE REGISTER (OPTIONAL) MEANINGFUL ONLY IF CARRY FLAG IS SET CARRY FLAG = CLEAR IF SUCCESSFUL SET IF UNSUCCESSFUL | CREATE_FILE MACRO ASCZ_OFF, ATT, HANDLE, ERROR IFNDEF $CREATE_FILE EXTRN $CREATE_FILE:NEAR ENDIF PUSH BP SUB SP, 3 MOV BP, SP MOV WORD PTR [BP], ASCZ_OFF IFB <ATT> MOV WORD PTR [BP+2], ATT ELSE MOV WORD PTR [BP+2], 0 ENDIF CALL $CREATE_FILE MOV HANDLE, WORD PTR [BP] IFNB <ERROR> MOV ERROR, [BP+2] ENDIF INC SP INC SP INC SP POP BP ENDM COMMENT | READ_STREAM MACRO ============================================= BIR ACIK DOSYADAN BYTE AKISINI OKUR DISK.LIB ICINDE $READ_STREAM PROSEDURU KULLANILIR. INPUT PARAMETERS: HANDLE = FILE HANDLE RETURNED BY OPEN OR CREATE WORD REGISTER OR IMMEDIATE BUFF_OFF = OFFSET OR RECORD BUFFER TO READ INTO WORD REGISTER IMMEDIATE MUST BE LONG ENOUGH FOR NUMBER OF CHARACTERS SPECIFIED BY BYTES INPUT/OUTPUT PARAMETERS: 389 BYTES = NUMBER BYTES TO READ/BYTES ACTUALLY READ WORD REGISTER OUTPUT PARAMETERS: ERROR = ERROR RETURNED BY DOS BYTE REGISTER (OPTIONAL) MEANINGFUL ONLY IF CARRY FALG SET CARRY FLAG CLEARED IF SUCCESSFUL, SET IF ERROR NOTE THAT NO ERROR IS RETURNED FOR END-OF-FILE. END-OF-FILE HAS OCCURED WHENEVER THE VALUE OF BAYTES ON OUTPUT IS LESS THAN ITS VALUE ON INPUT. | READ_STREAM MACRO HANDLE, BYTES, BUFF_OFF,ERROR IFNDEF $READ_STREAM EXTRN $READ_STREAM:NEAR ENDIF PUSH BP SUB SP, 6 MOV BP, SP MOV WORD PTR [BP], HANDLE MOV WORD PTR [BP+2], BUFF_OFF MOV WORD PTR [BP+4], BYTES CALL $READ_STREAM MOV BYTES, WORD PTR [BP+4] IFNB <ERROR> MOV ERROR, BYTE PTR [BP+3] ENDIF INC SP INC SP INC SP POP BP ENDM COMMENT | WRITE_STREAM MACRO ============================================= BIR ACIK DOSYAYA BYTE AKISINI YAZAR DISK.LIB ICINDE $WRITE_STREAM PROSEDURU KULLANILIR. INPUT PARAMETERS: HANDLE = FILE HANDLE RETURNED BY OPEN OR CREATE WORD REGISTER OR IMMEDIATE BUFF_OFF = OFFSET OR RECORD BUFFER TO READ INTO WORD REGISTER IMMEDIATE MUST BE LONG ENOUGH FOR NUMBER OF CHARACTERS SPECIFIED BY BYTES INPUT/OUTPUT PARAMETERS: BYTES = NUMBER BYTES TO WRITE/BYTES ACTUALLY READ WORD REGISTER IF 0 ON INPUT, TRUNCATRES OR EXTENDS FILE WARNING: DATA MAY BE LOST OUTPUT PARAMETERS: ERROR = ERROR RETURNED BY DOS BYTE REGISTER (OPTIONAL) MEANINGFUL ONLY IF CARRY FALG SET CARRY FLAG CLEARED IF SUCCESSFUL, SET IF ERROR NOTE THAT NO ERROR IS RETURNED FOR DISK-FULL. DISK-FULL HAS OCCURED WHENEVER THE VALUE OF BAYTES ON OUTPUT IS LESS THAN ITS VALUE ON INPUT. | 390 WRITE_STREAM MACRO HANDLE, BYTES, BUFF_OFF,ERROR IFNDEF $WRITE_STREAM EXTRN $WRITE_STREAM:NEAR ENDIF PUSH BP SUB SP, 6 MOV BP, SP MOV WORD PTR [BP], HANDLE MOV WORD PTR [BP+2], BUFF_OFF MOV WORD PTR [BP+4], BYTES CALL $WRITE_STREAM MOV BYTES, WORD PTR [BP+4] IFNB <ERROR> MOV ERROR, BYTE PTR [BP+3] ENDIF INC SP INC SP INC SP POP BP ENDM COMMENT | SEEK MACRO ===================================================== DOSYA GOSTERGECINI (KARAKTER ARACILIGIYLA) BIR DOSYA ILE AKIM DOSYALARINA DOGRUDAN ERISIM SAGLAR DISK.LIB ICINDE $SEEK PROSEDURU KULLANILIR. INPUT PARAMETERS: HANDLE = FILE HANDLE RETURNED BY OPEN OR CREATE WORD REGISTER OR IMMEDIATE MODE = METHOD FOR FILE-POINTER MOVEMENT BYTE REGISTER OR IMMEDIATE DEFAULT = 0 (ABSOLUTE) IMMEDIATE: BEG OR 0 = ABSOLUTE POS FROM BEGINING CUR OR 1 = RELATIVE TO CURRENT POSITION END OR 2 = RELATIVE TO END OF FILE REGISTER: 0 = ABSOLUTE POSITION FROM BEGINING 1 = RELATIVE TO CURRENT POSITION FROM BEGINNING 2 = RELATIVE TO END OF FILE INPUT/OUTPUT PARAMETERS: DISP_M = MSW OF DISPLACEMENT/NEW POSITION WORD REGISTER DISP_L = LSW OF DISPLACEMENT/NEW POSITION WORD REGISTER OUTPUT PARAMETERS: ERROR = ERROR RETURNED BY DOS BYTE REGISTER (OPTIONAL) MEANINGFUL ONLY IF CARRY FALG SET CARRY FLAG CLEARED IF SUCCESSFUL, SET IF ERROR | SEEK MACRO HANDLE, MODE, DISP_M, DISP_L, ERROR IFDEF $SEEK EXTRN $SEEK:NEAR ENDIF PUSH SUB BP SP, 7 391 MOV BP, SP MOV WORD PTR [BP], HANDLE IFB <MODE> MOV BYTE PTR [BP+2], 0 ELSE IFIDN <MODE>, <CUR> MOV BYTE PTR [BP+2], 1 ELSE IFIDN <MODE>, <END> MOV BYTE PTR [BP+2], 2 ELSE MOV BYTE PTR [BP+2], MODE ENDIF ENDIF ENDIF ENDIF MOV WORD PTR [BP+3], DISP_M MOV WORD PTR [BP+5], DISP_L CALL $SEEK MOV MOV IFB DISP_L, WORD PTR [BP+5] DISP_M, WORD PTR [BP+3] <ERROR> MOV ERROR, BYTE PTR [BP+2] ENDIF INC SP INC SP INC SP INC SP INC SP POP BP ENDM COMMENT | RSEEK MACRO ===================================================== DOSYA GOSTERGECINI (KARAKTER ARACILIGIYLA) BIR DOSYA ILE AKIM DOSYALARINA DOGRUDAN ERISIM SAGLAR DISK.LIB ICINDE $RSEEK PROSEDURU KULLANILIR. INPUT PARAMETERS: HANDLE = FILE HANDLE RETURNED BY OPEN OR CREATE WORD REGISTER OR IMMEDIATE MODE = METHOD FOR FILE-POINTER MOVEMENT BYTE REGISTER OR IMMEDIATE DEFAULT = 0 (ABSOLUTE) IMMEDIATE: BEG OR 0 = ABSOLUTE POS FROM BEGINING CUR OR 1 = RELATIVE TO CURRENT POSITION END OR 2 = RELATIVE TO END OF FILE REGISTER: 0 = ABSOLUTE POSITION FROM BEGINING 1 = RELATIVE TO CURRENT POSITION FROM BEGINNING 2 = RELATIVE TO END OF FILE R_LEN = RECORD LENGTH OF FILE WORD REGISTER OR IMMEDIATE INPUT/OUTPUT PARAMETERS: R_DISP = NUMBER OF RECORDS TO MOVE POINTER/NEW POSITION (NEW RECORD NUMBER) WORD REGISTER OUTPUT PARAMETERS: ERROR = ERROR RETURNED BY DOS 392 BYTE REGISTER (OPTIONAL) MEANINGFUL ONLY IF CARRY FALG SET CARRY FLAG CLEARED IF SUCCESSFUL, SET IF ERROR | SEEK MACRO HANDLE, MODE, R_LEN, R_DISP, ERROR IFDEF $RSEEK EXTRN $RSEEK:NEAR ENDIF PUSH BP SUB SP, 7 MOV BP, SP MOV WORD PTR [BP], HANDLE IFB <MODE> MOV BYTE PTR [BP+2], 0 ELSE IFIDN <MODE>, <CUR> MOV BYTE PTR [BP+2], 1 ELSE IFIDN <MODE>, <END> MOV BYTE PTR [BP+2], 2 ELSE MOV BYTE PTR [BP+2], MODE ENDIF ENDIF ENDIF ENDIF MOV WORD PTR [BP+3], R_LEN MOV WORD PTR [BP+5], R_DISP CALL $SEEK MOV IFB R_DISP, WORD PTR [BP+5] <ERROR> MOV ERROR, BYTE PTR [BP+4] ENDIF INC SP INC SP INC SP POP BP ENDM COMMENT | READ_CHR MACRO ================================================ ACIK BIR DOSYADAN BIR KARAKTER OKUR DISK.LIB ICINDE $READ_CHR PROSEDURU KULLANILIR. IN: OUT: | READ_CHR HANDLE = HANDLE OF FILE OF FILE TO READ FROM WORD REGISTER OR IMMEDIATE CHR_ERR = CHARACTER READ FROM FILE OR ERROR CODE RETURNED BY DOS OR 0 IF END OF FILE BYTE REGISTER CARRY = CLEAR IF SUCCESSFUL (CHR_ERR CONTAINS CHARACTER); SET IF ERROR OR END OF FILE (CHR_ERR CONTAINS ERROR) MACRO HANDLE, CHR_ERR IFNDEF $READ_CHR EXTRN $READ_CHR:NEAR ENDIF 393 PUSH DEC DEC MOV MOV CALL BP SP SP BP, SP WORD PTR [BP],HANDLE $READ_CHR MOV INC POP CHR_ERR, BYTE PTR [BP+1] SP BP ENDM COMMENT | READ_STR MACRO ================================================ DATA SEGMENTTE TAMPON ICINDE BIR TERMINAL FORMATLI DOSYADAN BIR STRING OKUR STRINGLER KYRUKTA SAKLANIR DISK.LIB ICINDE $READ_STR PROSEDURU KULLANILIR. INPUT PARAMTERS: HANDLE = HANDLE OF FILE TO READ FROM WORD REGISTER OR IMMEDIATE BUFFER_OFF = OFFSET OF BUFFER TO HOLD STRING WORD, REGISTER OR IMMEDIATE MAX_LEN = # OF CHARACTERS TO ALLOW BYTE, REGISTER OR IMMEDIATE DEFAULT = 80 BUFFER LENGTH MUST BE AT LEAST 1 MORE THAN MAX_LEN TRAILER = CHARACTER TO USE TO MARK END OF STRING BYTE, REGISTER OR IMMEDIATE DEFAULT = NUL (0) OUTPUT PARAMETERS: ERROR = ERROR CODE RETURNED BY DOS OR 0 IF END OF FILE OR 8 IF LINA TRUNCATED (BUFFER FULL) BYTE REGISTER (OPTIONAL) VALID ONLY IF CARRY SET CARRY = CLEAR IF SUCCESSFUL SET IF ERROR OR END OF FILE | READ_STR MACRO HANDLE, BUFF_OFF, MAX_LEN, TRAILER, ERROR IFNDEF $READ_STR EXTRN $READ_STR:NEAR ENDIF PUSH SUB BP SP, 6 MOV MOV MOV IFB BP, SP WORD PTR [BP], HANDLE WORD PTR [BP+2], BUFF_OFF <MAX_LEN> MOV BYTE PTR [BP+4], 80 ELSE MOV BYTE PTR [BP+4], MAX_LEN ENDIF IFB <TRAILER> MOV BYTE PTR [BP+5], 0 ELSE MOV BYTE PTR [BP+5], TRAILER 394 ENDIF CALL $READ_STR IFNB <ERROR> MOV ERROR, [BP+5] ENDIF INC SP POP BP ENDM COMMENT | READ_STRL MACRO ================================================ DATA SEGMENTTE TAMPON ICINDE BIR TERMINAL FORMATLI DOSYADAN BIR STRING OKUR STRINGLER BYTE OLARAK SAKLANIR DISK.LIB ICINDE $READ_STRL PROSEDURU KULLANILIR. INPUT PARAMTERS: HANDLE = HANDLE OF FILE TO READ FROM WORD REGISTER OR IMMEDIATE BUFFER_OFF = OFFSET OF BUFFER TO HOLD STRING WORD, REGISTER OR IMMEDIATE MAX_LEN = # OF CHARACTERS TO ALLOW BYTE, REGISTER OR IMMEDIATE DEFAULT = 80 BUFFER LENGTH MUST BE AT LEAST 1 MORE THAN MAX_LEN TRAILER = CHARACTER TO USE TO MARK END OF STRING BYTE, REGISTER OR IMMEDIATE DEFAULT = NUL (0) OUTPUT PARAMETERS: ERROR = ERROR CODE RETURNED BY DOS OR 0 IF END OF FILE OR 8 IF LINA TRUNCATED (BUFFER FULL) BYTE REGISTER (OPTIONAL) VALID ONLY IF CARRY SET CARRY = CLEAR IF SUCCESSFUL SET IF ERROR OR END OF FILE | READ_STR MACRO HANDLE, BUFF_OFF, MAX_LEN, TRAILER, ERROR IFNDEF $READ_STRL EXTRN $READ_STRL:NEAR ENDIF PUSH SUB BP SP, 5 MOV MOV MOV IFB BP, SP WORD PTR [BP], HANDLE WORD PTR [BP+2], BUFF_OFF <MAX_LEN> MOV BYTE PTR [BP+4], 80 ELSE MOV BYTE PTR [BP+4], MAX_LEN ENDIF IFB <MAX_LEN> MOV BYTE PTR [BP+4], 80 ELSE MOV BYTE PTR [BP+4], MAX_LEN ENDIF CALL $READ_STRL 395 IFNB <ERROR> MOV ERROR, [BP+4] ENDIF INC SP POP BP ENDM COMMENT | WRITE_CHR MACRO ================================================ ACIK BIR DOSYAYA BIR KARAKTER YAZAR DISK.LIB ICINDE $WRITE_CHR PROSEDURU KULLANILIR. IN: OUT: | READ_CHR HANDLE = HANDLE OF FILE OF FILE TO READ FROM WORD REGISTER OR IMMEDIATE CHAR = CHARACTER TO BE WRITTEN BYTE REGISTER OR IMMEDIATE ERROR = ERROR CODE RETURNED BY DOS BYTE REGISTER (OPTIONAL) VALID ONLY IF CARRY SET CARRY = CLEAR IF SUCCESSFUL SET IF ERROR MACRO HANDLE, CHAR, ERROR IFNDEF $WRITE_CHR EXTRN $WRITE_CHR:NEAR ENDIF PUSH SUB BP SP, 3 MOV MOV MOV CALL BP, SP WORD PTR [BP], HANDLE BYTE PTR [BP+2], CHAR $WRITE_CHR IFNB <ERROR> MOV ERROR, [ERROR] ENDIF INC POP SP BP ENDM COMMENT | WRITE_STR MACRO ================================================ DATA SEGMENTTE TAMPON ICINDE BIR TERMINAL FORMATLI DOSYAYA BIR STRING YAZAR STRINGLER KUYRUKTA SAKLANIR DISK.LIB ICINDE $WRITE_STR PROSEDURU KULLANILIR. INPUT PARAMETERS: HANDLE = HANDLE OF FILE TO WRITE FROM WORD REGISTER OR IMMEDIATE STR_OFF = OFFSET OIF STRING TO WRITE TO WORD, REGISTER OR IMMEDIATE TRAILER = CHARACTER TO USE TO MARK END OF STRING BYTE, REGISTER OR IMMEDIATE 396 DEFAULT = NUL (0) OUTPUT PARAMETERS: ERROR = ERROR CODE RETURNED BY DOS OR 0 IF DISK FULL BYTE REGISTER (OPTIONAL) VALID ONLY IF CARRY SET CARRY = CLEAR IF SUCCESSFUL SET IF ERROR OR END OF FILE NOTE: USE WRITE_CHR TO WRITE A SUB (26) TO THE END OF THE FILE CLOSING IT | READ_STRL MACRO HANDLE, STR_OFF, TRAILER, ERROR IFNDEF $WRITE_STR EXTRN $WRITE_STR:NEAR ENDIF PUSH SUB BP SP, 5 MOV MOV MOV IFB BP, SP WORD PTR [BP], HANDLE WORD PTR [BP+2], STR_OFF <TRAILER> MOV BYTE PTR [BP+4], 0 ELSE MOV BYTE PTR [BP+4], TRAILER ENDIF CALL $WRITE_STR IFNB <ERROR> MOV ERROR, [BP+4] ENDIF INC SP POP BP ENDM COMMENT | WRITE_STRL MACRO ================================================ DATA SEGMENTTE TAMPON ICINDE BIR TERMINAL FORMATLI DOSYAYA BIR STRING YAZAR STRINGLER BYTE OLARAK SAKLANMALI DISK.LIB ICINDE $WRITE_STRL PROSEDURU KULLANILIR. INPUT PARAMTERS: HANDLE = HANDLE OF FILE TO READ FROM WORD REGISTER OR IMMEDIATE STR_OFF = OFFSET OF STRING TO WRITE TO WORD, REGISTER OR IMMEDIATE OUTPUT PARAMETERS: ERROR = ERROR CODE RETURNED BY DOS OR 0 IF DISK FULL BYTE REGISTER (OPTIONAL) VALID ONLY IF CARRY SET CARRY = CLEAR IF SUCCESSFUL SET IF ERROR OR END OF FILE NOTE: USE WRITE_CHR TO WRITE A SUB (26) TO THE END OF THE FILE CLOSING IT | WRITE_STRL MACRO HANDLE, STR_OFF, ERROR IFNDEF $WRITE_STRL EXTRN $WRITE_STRL:NEAR 397 ENDIF PUSH SUB BP SP, 4 MOV MOV MOV CALL BP, SP WORD PTR [BP], HANDLE WORD PTR [BP+2], STR_OFF $WRITE_STRL IFNB <ERROR> MOV ERROR, [BP+3] ENDIF INC SP POP BP ENDM COMMENT | WRITE_IMMED_STR MACRO =========================================== TERMINAL FORMATLI DOSYAYA ANLIK STRING YAZAR WRITE_STR MACRO ALTINDA KULLANILIR INPUT PARAMETERS: HNDL = HANDLE OF FILE TO WRITE TO WORD REGISTER OR IMMEDIATE STRING = STRING TO DISPLAY IMMEDIATE VALUE(S) TRLR = CHARACTER TO USE TO MAR KEND OF STRING BYTE, REGISTER OR IMMEDIATE DAFAULT = NUL (0) OUTPUT PARAMETERS: ERROR = ERROR CODE RETURNED BY DOS OR 0 IF DISK FULL BYTE REGISTER (OPTIONAL) VALID ONLY IF CARRY SET CARRY = CLEAR IF SUCCESSFUL SET IF ERROR OR END OF FILE | WRITE_IMMED_STR MACRO HNDL, STRING ,TRLR, ERROR LOCAL STR_BFR DATA STR_BFR SEGMENT DB STRING IFB <TRLR> DB 0 ELSE DB TRLR ENDIF ENDS WRITE_STR <HNDL>,<OFFSET STR_BFR>,<TRLR>,<ERROR> DATA ENDM COMMENT | CLOSE_FILE MACRO ============================================== ACIK BIR DOSYAYI KAPATIR DISK.LIB ICINDE $CLOSE_FILE PROSEDURU KULLANILIR. INPUT PARAMTERS: HANDLE = HANDLE RETURNED BY OPEN FILE OR CREATE_FILE 398 WORD REGISTER OR IMMEDIATE OUTPUT PARAMETERS: ERROR = ERROR CODE RETURNED BY DOS BYTE REGISTER (OPTIONAL) VALID ONLY IF CARRY SET CARRY FLAG CLEARED IF SUCCESSFUL, SET IF ERROR | CLOSE_FILE MACRO HANDLE, ERROR IFNDEF $CLOSE_FILE:NEAR EXTRN $CLOSE_FILE:NEAR ENDIF PUSH DEC DEC MOV MOV CALL BP SP SP BP, SP WORD PTR [BP], HANDLE $CLOSE_FILE IFNB <ERROR> MOV ERROR, [BP+1] ENDIF INC SP POP BP ENDM COMMENT | $SEL_DTA.ASM Kadir Geckin DISK TRANSFER ADRESINI (DTA) AYARLAYAN ALT PROSEDUR. SET_DTA MACRO TARAFINDAN KULLANILIR. INPUT PARAMETERS: OFFSET OF DATA SEGMENT WORD AT [BP+0] OUTPUT PARAMETERS: NONE CLOSE 2-BYTE STACK HOLE OPEN ALL REGISTER RESTORED | TITLE $SEL_SEF.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA 399 DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $SEL_DEF PROC NEAR PUBLIC $SEL_DTA $SET_DTA CODE PUSH AX PUSH DX MOV DX, [BP] MOV AH,1AH INT 21H MOV [BP], AL POP DX POP AX RET 2 ENDP ENDS END COMMENT | $SEL_DTA.ASM Kadir Geckin DISK TRANSFER ADRESINI (DTA) AYARLAYAN ALT PROSEDUR. SET_DTA MACRO TARAFINDAN KULLANILIR. INPUT PARAMETERS: OFFSET OF DATA SEGMENT WORD AT [BP+0] OUTPUT PARAMETERS: NONE CLOSE 2-BYTE STACK HOLE OPEN ALL REGISTER RESTORED | TITLE $SEL_SEF.ASM PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $SET_DTA PROC NEAR PUBLIC $SET_DTA 400 $SET_DTA CODE PUSH AX PUSH DX MOV DX, [BP] MOV AH,1AH INT 21H MOV [BP], AL POP DX POP AX RET 2 ENDP ENDS END COMMENT | $STL_SCZ.ASM BYTLE'LA SAKLI STRINGI ASCIIZ STRINGINE CEVIRIR CNV_STRL_ASCZ MACRO TRAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF STRING TO CONVERT WORD AT [BP+0] OUTPUT PARAMETERS: NONE ALL REGISTERS RESTORED | CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $CNV_STRL_ASCZ $CNV_STRL_ASCZ CODE COMMENT | PROC NEAR PUBLIC $CNV_STRL_ASCZ PUSH PUSH PUSH PUSH PUSH PUSH POP MOV MOV LODSB MOV SUB REP SUB STOSB POP POP POP POP POP RET ENDP ENDS END AX CX SI DI ES DS ES SI, [BP] DI, SI CL, AL CH, CH MOVSB AL, AL ES DI SI CX AX 2 $GET_ATT.ASM 401 ALTDIZIN YARATIR GET_ATT MACROSU TARAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF ASCIIZ DRIVE AND PATH WORD AT [BP+0] OUTPUT PARAMETERS: ERROR BYTE AT [BP+1] DO NOT CLOSE 2-BYTE STACK HOLE CARRY FLAG SET IF ERROR ALL OTHER REGISTER RESTORED | CODE $GET_ATT $GET_ATT CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE PROC PUBLIC NEAR $GET_ATT PUSH PUSH PUSH MOV MOV INT MOV MOV POP POP POP RET AX CX DX DX, [BP+0] AX, 4300H 21H [BP+0], CL [BP+1], AL DX CX AX ENDP ENDS END COMMENT | $GET_DEF.ASM Kadir Geckin VARSAYILAN DISK SURUCUSUNU OLUSTURAN ALT PROSEDUR. GET_DEF MACRO TARAFINDAN KULLANILIR. INPUT PARAMETERS: NONE OUTPUT PARAMETERS: CURRENT DEFAULT DRIVE BYTE AT [BP+0] LEAVES I-BYTE STACK HOLE OPEN ALL REGISTER RESTORED | TITLE $SEL_SEF.ASM 402 PAGE 55,80 DATA SEGMENT WORD PUBLIC 'DATA' ASSUME DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $GET_DEF PROC NEAR PUBLIC $GET_DEF PUSH PUSH MOV MOV INT MOV POP ENDP ENDS END $GET_DEF CODE COMMENT | AX DX DL, [BP] AH,19H 21H [BP], AL AX $GET_DIR.ASM GUNCEL ALT DIZINI ELDE EDER GET_DIR MACRO TARAFINDAN KULLANILIR INPUT PARAMETERS: DRIVE TO OBTAIN CURRENT SUBDIRECTORY FOR BYTE AT [BP+0] OFFSET OF BUFFER TO RECEIVE ASCIIZ AND PATH WORD AT [BP+1] OUTPUT PARAMETERS: ERROR BYTE AT [BP+2] CLOSES 2 BYTES OF 3-BYTE STACK HOLE CARRY FLAG SET IF ERROR ALL OTHER REGISTERS RESTORED | CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $GET_DIR PROC PUBLIC NEAR $GET_DIR PUSH PUSH PUSH AX DX SI MOV MOV MOV INT DL, [BP+0] SI, [BP+1] AH, 47H 21H 403 MOV POP POP POP RET $GET_DIR CODE [BP+1], AL SI DX AX 2 ENDP ENDS END COMMENT | $GET_DTA.ASM Kadir Geckin DISK TRANSFER ADRESINI (DTA) ELDE EDEN PROSEDUR. GET_DTA MACRO TARAFINDAN KULLANILIR. INPUT PARAMETERS: NONE OUTPUT PARAMETERS: OFFSET (WORD) AND SEGMENT (WORD) OF DATA ON STACK (4 BYTE HOLE) [BP+0] = DTA_OFF [BP+2] = DTA_SEG DOES NOT CLOSE 4 BYTE STACK HOLE ALL OTHER REGISTERS RESTORED | CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $GET_DTA PROC NEAR PUBLIC $GET_DTA $GET_DTA CODE COMMENT | PUSH PUSH PUSH MOV INT MOV MOV POP POP POP RET ENDP ENDS END AX BX ES AH,2FH 21H [BP], BX [BP+2], ES ES BX AX 2 $GET_SPC.ASM DISKIN TABLOLAMA BILGISINI ALIR 404 GET_DSK_SPACE MACRO TARAFINDAN KULLANILIR INPUT PARAMTERS: NEW DEFAULT DRIVE BYTE AT [BP+0] OUTPUT PARAMTERS: NUMBER OF FREE CLUSTERS WORD AT [BP+0] NUMBER OF TOTAL CLUSTERS WORD AT [BP+2] CLUSTER SIZE WORD AT [BP+4] SECTOR SIZE WORD AT [BP+6] DOES NOT CLOSE 8 BYTE STACK HOLE ALL OTHER REGISTER RESTORED | CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $GET_DSK_SPACE PROC NEAR PUBLIC $GET_DSK.ASM $GET_DSK_SPACE CODE COMMENT | PUSH PUSH PUSH PUSH MOV MOV INT MOV MOV MOV MOV POP POP POP POP POP RET ENDP ENDS ENDM AX BX CX DX DL, [BP+0] AH, 36H 21H [BP+0], BX [BP+2], DX [BP+4], AX [BP+6], CX DX CX BX BX AX $DIR_FST.ASM ILK DIZIN GIRIS ESLEMESI ICIN ARAMA YAPAR DIR_FRST MACROSU TARAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF ASCIIZ DRIVE AND PATH WORD AT [BP+0] ATTRIBUTE TO USE IN SEARCH BYTE AT [BP+2] 405 OUTPUT PARAMETERS: ERROR BYTE AT [BP+2] CLOSES 3 BYTES OF 3-BYTE STACK HOLE CARRY FLAG SET IF ERROR ALL OTHER REGISTER RESTORED | CODE $DIR_FRST $DIR_FRST CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE PROC PUBLIC NEAR $DIR_FRST PUSH PUSH PUSH AX CX DX MOV MOV SUB MOV INT MOV POP POP POP RET DX, [BP+0] CL, [BP+2] CH, CH AH, 4EH 21H [BP+2], AL DX CX AX 2 ENDP ENDS END COMMENT | $DIR_NXT.ASM DIR_FRTS DEN SONRA YENI DIZIN GIRIS ESLEMESI ICIN ARAMA YAPAR DIR_NXT MACROSU TARAFINDAN KULLNILIR INPUT PARAMETERS: NONE OUTPUT PARAMTERS: ERROR BYTE AT [BP+0] LEAVES 1-BYTE STACK HOLE OPEN CARRY FLAG SET IF ERROR ALL OTHER REGISTERS RESTORED | CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $DIR_NXT PROC NEAR PUBLIC $DIR_NXT PUSH AX MOV AH, 4FH INT 21H MOV [BP+0], AL POP AX RET $DIR_NXT ENDP 406 CODE ENDS END COMMENT | $MKDIR.ASM ALTDIZIN YARATIR MKDIR MACRO TARAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF ASCIIZ DRIVE AND PATH WORD AT [BP+0] OUTPUT PARAMETERS: ERROR BYTE AT [BP+1] CLOSES 1 BYTE OF 2-BYTE STACK HOLE CARRY FLAG SET IF ERROR ALL OTHER REGISTERS RESTORED | CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $MKDIR PROC NEAR PUBLIC $MKDIR PUSH PUSH MOV MOV INT MOV POP POP RET ENDP ENDS END $MKDIR CODE COMMENT | AX DX DX, [BP+0] AH, 39H 21H [BP+1], AL DX AX 1 $CHDIR.ASM GUNCEL DIZINI DEGISTIRIR CHDIR MACROSU TARAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF ASCIIZ DRIVE AND PATH WORD AT [BP+0] OUTPUT PARAMETERS: ERROR BYTE AT [BP+1] CLOSES 1 BYTE OF 2-BYTE STACK HOLE CARRY FLAG SET IF ERROR ALL OTHER REGISTERS RESTORED 407 | CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $CHDIR $CHDIR CODE PROC PUBLIC NEAR $CHDIR PUSH PUSH MOV MOV INT MOV POP POP RET ENDP ENDS END AX DX DX, [BP+0] AH, 3BH 21H [BP+1], AL DX AX 1 COMMENT | $RMDIR.ASM DIZIN SILER RMDIR MACROSU TARAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF ASCIIZ DRIVE AND PATH WORD AT [BP+0] OUTPUT PARAMETERS: ERROR BYTE AT [BP+1] CLOSES 1 BYTE OF 2-BYTE STACK HOLE CARRY FLAG SET IF ERROR ALL OTHER REGISTERS RESTORED | CODE $MKDIR $MKDIR CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE PROC NEAR PUBLIC $RMDIR PUSH PUSH MOV MOV INT MOV POP POP RET ENDP ENDS END AX DX DX, [BP+0] AH, 3AH 21H [BP+1], AL DX AX 1 408 COMMENT | $CHG_ATT.ASM DOSYANIN OZELLIGINI DEGISTIRIR CHG_ATT MACROSU TARAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF ASCIIZ DRIVE AND PATH WORD AT [BP+0] NEW ATTRIBUTE FOR FILE BYTE AT [BP+2] OUTPUT PARAMETERS: ERROR BYTE AT [BP+2] CLOSES 2 BYTES OF 3-BYTE STACK HOLE CARRY FLAG SET IF ERROR ALL OTHER REGISTER RESTORED | CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $CHG_ATT $CHG_ATT CODE COMMENT | PROC PUBLIC NEAR $CHG_ATT PUSH PUSH PUSH MOV MOV SUB MOV INT MOV POP POP POP RET AX CX DX DX, [BP+0] CL, [BP+2] CH, CH AX, 4301H 21H [BP+2], AL DX CX AX 2 ENDP ENDS END $SEEK.ASM KARAKTER TARAFINDAN DOSYA ISARETCISINI KONUMLANDIRAN PROSEDUR SEEK MACROSU TARAFINDAN KULLANILIR INPUT PARAMETERS: FILE HANDLE WORD AT [BP+0] OFFSET OF RECORD BUFFER (TO WRTIE FROM) 409 BYTE AT [BP+2] INPUT/OUTPUT PARAMETERS: MOST SIGNIFICANT WORD OF DISPLACEMENT/NEW POSITION WORD AT [BP+3] LEASET SIG WORD OF DISPLACEMENT/NEW POSITION WORD AT [BP+5] OUTPUT PARAMETERS: ERROR RETURNED BY DOS BYTE AT [BP+2] CARRY FLAG CLEAR SUCCESSFUL SET IF ERROR LEAVES 5-BYTE OF STACK HOLE OPEN ALL OTHER REGISTERS RESTORED | DATA SEGMENT WORD PUBLIC 'DATA' DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE, DS:DATA $SEEK PROC NEAR PUBLIC $SEEK PUSH PUSH PUSH PUSH MOV MOV MOV MOV MOV INT AX BX CX DX BX, AL, CX, DX, AH, 21H MOV MOV MOV [BP+2], AL [BP+3], DX [BP+5], AX RS_RET: POP POP POP POP RET $SEEK CODE ENDP ENDS END COMMENT | [BP] [BP+2] [BP+3] [BP+5] 42H DX CX BX AX 2 $RSEEK.ASM 410 KAYIT TARAFINDAN DOSYA ISARETCISINI KONUMLANDIRAN PROSEDUR RSEEK MACROSU TARAFINDAN KULLANILIR INPUT PARAMETERS: FILE HANDLE WORD AT [BP+0] MODE FOR POINTER MOVEMENT BYTE AT [BP+2] RECORD LENGHT WORD AT [BP+3] INPUT/OUTPUT PARAMETERS: NUMBER OF RECORDS TO MOVE FILE POINTER WORD AT [BP+5] OUTPUT PARAMETERS: ERROR RETURNED BY DOS BYTE AT [BP+2] CARRY FLAG CLEAR SUCCESSFUL SET IF ERROR LEAVES 3 BYTE OF STACK HOLE OPEN ALL OTHER REGISTERS RESTORED | IF1 INCLUDE DISK.MLB ENDIF DATA SEGMENT WORD PUBLIC 'DATA' DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE, DS:DATA $RSEEK PROC NEAR PUBLIC $RSEEK PUSH PUSH PUSH PUSH AX BX CX DX MOV IMUL MOV MOV SEEK PUSHF DIV POPF MOV MOV AX, [BP+5] WORD PTR [BP+3] BX, [BP] CH, [BP+2] BX, CH, DX, AX, CL POP POP WORD PTR [BP+3] [BP+4], CL [BP+5], AX DX CX 411 POP POP RET $RSEEK CODE BX AX 4 ENDP ENDS END COMMENT | $OPEN.ASM YENI DOSYA ACAN PROSEDUR OPEN_FILE MACROSU TARAFINDAN KULLANILIR INPUT PARAMETERS: ASCIIZ OFFSET WORD AT [BP+0] FILE MODE BYTE AT [BP+2] OUTPUT PARAMETERS: FILE HANDLE RETURNED BY DOS WORD AT [BP+0] ERROR RETURNED BY DOS BYTE AT [BP+2] CARRY FLAG CLEAR SUCCESSFUL SET IF ERROR LEAVES 3-BYTE STACK HOLE OPEN ALL OTHER REGISTERS RESTORED | DATA SEGMENT WORD PUBLIC 'DATA' DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE, DS:DATA $OPEN_FILE PROC NEAR PUBLIC $OPEN_FILE PUSH AX PUSH DX MOV DX, [BP] MOV AL, [BP+2] MOV AH, 3DH INT 21H JC OF_ERR MOV [BP], AX MOV BYTE PTR [BP+2], 0 JMP SHORT OF_RET OF_ERR: MOV [BP+2], AL 412 MOV OF_RET: POP POP RET $OPEN_FILE CODE ENDP ENDS END COMMENT | WORD PTR [BP], 0 DX AX $CREATE.ASM YENI BIR DOSYA YARATAN PROSEDUR CREATE_FILE MACROSU TARAFINDAN KULLANILIR INPUT PARAMETERS: ASCIIZ OFFSET WORD AT [BP+0] ATTRIBUTE BYTE BYTE AT [BP+2] OUTPUT PARAMETERS: FILE HANDLE RETURNED BY DOS WORD AT [BP+0] ERROR RETURNED BY DOS BYTE AT [BP+2] CARRY FLAG CLEAR SUCCESSFUL SET IF ERROR LEAVES 3-BYTE STACK HOLE OPEN ALL OTHER REGISTERS RESTORED | DATA SEGMENT WORD PUBLIC 'DATA' DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE, DS:DATA $CREATE_FILE PROC NEAR PUBLIC $CREATE_FILE PUSH AX PUSH CX PUSH DX MOV DX, [BP] MOV CL, [BP+2] SUB CH, CH MOV AH, 3CH INT 21H JC CF_ERR MOV [BP], AX 413 MOV JMP CF_ERR: CF_RET: POP POP POP RET $CREATE_FILE CODE ENDP ENDS END BYTE PTR [BP+2], 0 SHORT CF_RET MOV [BP+2], AL MOV WORD PTR [BP], 0 COMMENT | DX CX AX $CLOSE.ASM BIR DOSYAYI KAPATAN PROSEDUR CLOSE_FILE MACRO TARAFINDAN KULLANILIR INPUT PARAMTERS: HANDLE OF FILE TO CLOSE WORD AT [BP+0] OUTPUT PARAMETERS: ERROR RETURNED BY DOS BYTE AT [BP+1] CARRY FLAG CLEAR IF SUCCESSFUL SET IF ERROR LEAVES 1 BYTE STACK HOLE OPEN ALL OTHER REGISTERS RESTORED | DATA SEGMENT DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE, DS:DATA $CLOSE_FILE PROC PUBLIC NEAR $CLOSE_FILE PUSH PUSH AX BX MOV MOV INT JC JMP CF_ERR: WORD PUBLIC 'DATA' BX, [BP] AH, 3EH 21H CF_ERR MOV BYTE PTR [BP+1], 0 SHORT CF_RET MOV [BP+1], AL 414 CF_RET: POP POP RET $CLOSE_FILE CODE ENDP ENDS END COMMENT | DX AX 2 $READ.ASM DOSYA AKIMINDAN OKUYAN PROSEDUR READ_STREAM MACROSU TARAFINDAN KULLANILIR INPUT PARAMETERS: FILE HANDLE WORD AT [BP+0] OFFSET OF RECORD BUFFER (TO READ TO) WORD AT [BP+2] INPUT/OUTPUT PARAMETERS: BYTES TO READ/BYTES ACTUALLY READ WORD AT [BP+4] OUTPUT PARAMETERS: ERROR RETURNED BY DOS BYTE AT [BP+3] CARRY FLAG CLEAR SUCCESSFUL SET IF ERROR LEAVES 3-BYTE STACK HOLE OPEN ALL OTHER REGISTERS RESTORED | DATA SEGMENT WORD PUBLIC 'DATA' DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE, DS:DATA $READ_STREAM PROC NEAR PUBLIC $READ_STREAM PUSH PUSH PUSH PUSH MOV MOV MOV AX BX CX DX BX, [BP] DX, [BP+2] CX, [BP+4] MOV INT AH, 3FH 21H 415 JC RS_ERR [BP+4], AX BYTE PTR [BP+3], 0 JMP SHORT RS_RET MOV [BP+3], AL MOV WORD PTR [BP+4], 0 MOV MOV RS_ERR: RS_RET: POP POP POP POP RET $READ_STREAM CODE ENDP ENDS END COMMENT | DX CX BX AX 3 $READ_CH.ASM TERMINAL FORMATLI DOSYADAN 1 KARAKTER OKUYAN PROSEDUR READ_CHR MACRO TARAFINDAN KULLANILIR INPUT PARAMTERS: FILE HANDLE WORD AT [BP+0] OUTPUT PARAMETERS: CHARACTER READ FROM THE FILE OR ERROR CODE BYTE AT [BP+1] CARRY FLAG CLEAR IF SUCCESSFUL (CHARACTER RETURNED) SET IF ERROR (ERROR RETURNED) CLOSE 1 BYTE OF 2-BYTE STACK HOLE ALL OTHER REGISTERS RESTORED | DATA SEGMENT WORD PUBLIC 'DATA' CHR_BFR DB DATA ENDS ? CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE, DS:DATA $READ_CHR PROC NEAR PUBLIC $READ_CHR PUSH PUSH PUSH PUSH MOV MOV MOV AX BX CX DX BX, [BP] DX, OFFSET CHR_BFR CX, 1 MOV AH, 3FH 416 INT JC CMP JC C_1: C_2: RC_NET: $READ_CHR CODE 21H C_2 AL, 1 C_1 MOV AL, CHR_BFR MOV [BP+1], AL POP DX POP CX POP BX POP AX RET 1 ENDP ENDS END COMMENT | $READ_ST.ASM TERMINAL FORMATLI DOSYADAN 1 STRING OKUYAN PROSEDUR STRING BYTE UZUNLUGUNDA SAKLANIR, DATA SEGMENTIN BIR TAMPONUNDA... READ_STRL MACRO TARAFINDAN KULLANILIR READ_CHR YAPITASINI KULLANIR INPUT PARAMTERS: HANDLE OF FILE TO READ FROM SIZE SIZE: WORD LOCATION: [BP+0] OFFSET OF BUFFER TO RECEIVE STRING SIZE: WORD LOCATION: [BP+2] MAXIMUM MUMBER OF CHARACTER TO ALLOW SIZE: BYTE LOCATION: [BP+4] OUTPUT PARAMETERS: ERROR RETURNED BY READ_CHR OR 8 IF BUFFER FULL SIZE: BYTE LOCATION: [BP+4] CARRY SET IF ERROR, CLEAR UF SUCCESSFUL CLOSE 4 BYTE OF 5-BYTE STACK HOLE ALL OTHER REGISTERS RESTORED | TITLE $READ_ST.ASM PAGE 55, 80 INCLUDE DISK.MLB DATA SEGMENT ASSUME WORD PUBLIC 'DATA' DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE 417 $READ_STRL PROC NEAR PUBLIC $READ_STRL PUSH PUSH PUSH PUSH PUSH MOV MOV INC MOV MOV SUB CHR_LOOP: JC CMP JE CMP JNE SUB STC JMP C_1: AX BX CX DX SI BX, SI, SI CX, DL, DH, JMP LP_END: JC 0 [BP+4] DH READ_CHR LP_END AL, 13 LP_END AL, 26 C_1 AL ,AL INC CMP JA C_2: [BP] [BP+2] BX, AL LP_END CX CX, DX C_2 MOV [SI], AL INC SI CHR_LOOP C_4 READ_CHR BX, AL CMP DX, CX JAE C_3 MOV AL, 8 C_3: C_4: MOV MOV MOV POP POP POP POP POP RET $READ_STR CODE COMMENT | SI, [BP+2] [SI], CL [BP+4], AL SI DX CX BX AX 4 ENDP ENDS END $READ_ST.ASM TERMINAL FORMATLI DOSYADAN 1 STRING OKUYAN PROSEDUR STRING KUYRAUKTA SAKLANIR, DATA SEGMENTIN BIR TAMPONUNDA... 418 READ_STR MACRO TARAFINDAN KULLANILIR READ_CHR YAPITASINI KULLANIR INPUT PARAMTERS: HANDLE OF FILE TO READ FROM SIZE SIZE: WORD LOCATION: [BP+0] OFFSET OF BUFFER TO RECEIVE STRING SIZE: WORD LOCATION: [BP+2] MAXIMUM MUMBER OF CHARACTER TO ALLOW SIZE: BYTE LOCATION: [BP+4] TRAILER TO USE ON STRING SIZE: BYTE LOCATION: [BP+5] OUTPUT PARAMETERS: ERROR RETURNED BY READ_CHR OR 8 IF BUFFER FULL SIZE: BYTE LOCATION: [BP+5] CARRY SET IF ERROR, CLEAR UF SUCCESSFUL CLOSE 5 BYTE OF 6-BYTE STACK HOLE ALL OTHER REGISTERS RESTORED | TITLE $READ_ST.ASM PAGE 55, 80 INCLUDE DISK.MLB DATA SEGMENT ASSUME WORD PUBLIC 'DATA' DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $READ_STR PROC NEAR PUBLIC $READ_STR PUSH PUSH PUSH PUSH PUSH MOV MOV SUB CHR_LOOP: JC CMP JE CMP JNE SUB STC JMP C_1: AX BX CX DX SI BX, [BP] SI, [BP+4] DH, DH READ_CHR BX, AL LP_END AL, 13 LP_END AL, 26 C_1 AL ,AL INC CMP JA LP_END CX CX, DX C_2 MOV [SI], AL 419 C_2: JMP LP_END: JC INC SI CHR_LOOP C_4 READ_CHR BX, AL CMP DX, CX JAE C_3 MOV AL, 8 C_3: C_4: MOV MOV MOV POP POP POP POP POP RET $READ_STR CODE AH, [BP+5] [SI], AH [BP+5], AL SI DX CX BX AX 5 ENDP ENDS END COMMENT | $REN_FIL.ASM ALTDIZIN SILER RMDIR MACROSU TARAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF ASCIIZ DRIVE AND PATH WORD AT [BP+0] OUTPUT PARAMETERS: ERROR BYTE AT [BP+1] CLOSES 1 BYTE OF 2-BYTE STACK HOLE CARRY FLAG SET IF ERROR ALL OTHER REGISTERS RESTORED | CODE $REN_FILE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE PROC PUBLIC PUSH PUSH MOV MOV INT MOV POP POP RET NEAR $REN_FILE AX DX DX, [BP+0] AH, 3AH 21H [BP+1], AL DX AX 1 420 $REN_FILE CODE ENDP ENDS END COMMENT | $DEL_FIL.ASM DOSYA SILER DEL_FILE MACROSU TARAFINDAN KULLANILIR INPUT PARAMETERS: OFFSET OF ASCIIZ DRIVE AND PATH WORD AT [BP+0] OUTPUT PARAMETERS: ERROR BYTE AT [BP+1] CLOSES 1 BYTE OF 2-BYTE STACK HOLE CARRY FLAG SET IF ERROR ALL OTHER REGISTER RESTORED | CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $DEL_FILE $DEL_FILE CODE PROC PUBLIC NEAR $DEL_FILE PUSH PUSH AX DX MOV MOV INT DX, [BP+0] AX, 41H 21H MOV POP POP POP RET [BP+1], AL DX CX AX 1 ENDP ENDS END COMMENT | $WRITE.ASM DOSYA AKIMINA YAZAN PROSEDUR WRITE_STREAM MACROSU TARAFINDAN KULLANILIR INPUT PARAMETERS: FILE HANDLE WORD AT [BP+0] 421 OFFSET OF RECORD BUFFER (TO WRTIE FROM) WORD AT [BP+2] INPUT/OUTPUT PARAMETERS: BYTES TO WRITE/BYTES ACTUALLY WRITTEN WORD AT [BP+4] OUTPUT PARAMETERS: ERROR RETURNED BY DOS BYTE AT [BP+3] CARRY FLAG CLEAR SUCCESSFUL SET IF ERROR LEAVES 3-BYTE STACK HOLE OPEN ALL OTHER REGISTERS RESTORED | DATA SEGMENT WORD PUBLIC 'DATA' DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE, DS:DATA $WRITE_STREAM PROC NEAR PUBLIC $WRITE_STREAM PUSH PUSH PUSH PUSH MOV MOV MOV AX BX CX DX BX, [BP] DX, [BP+2] CX, [BP+4] MOV INT JC WS_ERR: WS_RET: AH, 40H 21H WS_ERR MOV [BP+4], AX MOV BYTE PTR [BP+3], 0 JMP SHORT WS_RET MOV [BP+3], AL MOV WORD PTR [BP+4], 0 POP POP POP POP RET DX CX BX AX 3 $WRITE_STREAM ENDP CODE ENDS END COMMENT | $WRTE_CH.ASM 422 TERMINAL FORMATLI DOSYAYA 1 KARAKTER YAZAN PROSEDUR WRITE_CHR MACRO TARAFINDAN KULLANILIR INPUT PARAMTERS: FILE HANDLE WORD AT [BP+0] CHARACTER WRITE TO FILE BYTE AT [BP+2] OUTPUT PARAMETERS: ERROR RETURNED BY DOS BYTE AT [BP+2] CARRY FLAG CLEAR IF SUCCESSFUL SET IF ERROR CLOSE 1 BYTE OF 2-BYTE STACK HOLE ALL OTHER REGISTERS RESTORED | DATA SEGMENT WORD PUBLIC 'DATA' CHR_BFR DB DATA ENDS ? CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE, DS:DATA $WRITE_CHR PROC NEAR PUBLIC $WRITE_CHR PUSH PUSH PUSH PUSH MOV MOV MOV MOV MOV AX BX CX DX BX, [BP+2] CHR_BFR, AL BX, [BP] DX, OFFSET CHR_BFR CX, 1 MOV INT AH, 40H 21H JC CMP JC WC_ERR: WC_RET: $WRITE_CHR WC_ERR AL, 1 WC_ERR MOV BYTE PTR [BP+2], 0 JMP SHORT WC_RET MOV [BP+2], AL POP POP POP POP RET DX CX BX AX 2 ENDP 423 CODE ENDS END COMMENT | $WRTE_SL.ASM TERMINAL FORMATLI DOSYAYA 1 STRING YAZAN PROSEDUR STRING BYTE UZUNLUGUNDA SAKKLANIR, DATA SEGMENTIN BIR TAMPONUNDA... WRITE_CHR YAPITASINI KULLANIR INPUT PARAMTERS: HANDLE OF FILE TO WRITE TO SIZE: WORD LOCATION: [BP+0] OFFSET OF THE STRING SIZE: WORD LOCATION: [BP+2] OUTPUT PARAMETERS: ERROR RETURNED BY READ_CHR OR 8 IF BUFFER FULL SIZE: BYTE LOCATION: [BP+5] CARRY SET IF ERROR, CLEAR UF SUCCESSFUL CLOSES 3 BYTE OF 4-BYTE STACK HOLE ALL OTHER REGISTERS RESTORED | INCLUDE DISK.MLB TITLE PAGE $WRTE_SL.ASM 55, 80 DATA SEGMENT ASSUME DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $WRITE_STRL PROC PUBLIC NEAR $WRITE_STRL PUSH PUSH PUSH PUSH AX BX CX DX MOV MOV DX, [BP+0] BX, [BP+2] LP_BEG: WORD PUBLIC 'DATA' DS:DATA MOV CL, [BX] SUB CH, CH INC BX JCXZ LP_END MOV AL, [BX] WRITE_CHR DX, AL, AH JC EXIT INC BX JMP LP_BEG 424 LP_END: EXIT: $WRITE_STRL CODE MOV POP POP POP POP RET [BP+3], AH DX CX BX AX 3 ENDP ENDS END COMMENT | $WRTE_ST.ASM TERMINAL FORMATLI DOSYAYA 1 STRING YAZAN PROSEDUR STRING KUYRUKTA SAKLANIR, DATA SEGMENTIN BIR TAMPONUNDA... WRITE_CHR YAPITASINI KULLANIR INPUT PARAMTERS: HANDLE OF FILE TO WRITE TO SIZE: WORD LOCATION: [BP+0] OFFSET OF THE STRING SIZE: WORD LOCATION: [BP+2] TRAILER CHARACTER SIZE: BYTE LOCATION: [BP+4] OUTPUT PARAMETERS: ERROR RETURNED BY READ_CHR OR 8 IF BUFFER FULL SIZE: BYTE LOCATION: [BP+4] CARRY SET IF ERROR, CLEAR UF SUCCESSFUL CLOSES 4 BYTE OF 5-BYTE STACK HOLE ALL OTHER REGISTERS RESTORED | INCLUDE DISK.MLB TITLE PAGE $WRTE_ST.ASM 55, 80 DATA SEGMENT ASSUME WORD PUBLIC 'DATA' DS:DATA DATA ENDS CODE SEGMENT WORD PUBLIC 'CODE' ASSUME CS:CODE $WRITE_STR PROC PUBLIC NEAR $WRITE_STR PUSH PUSH PUSH AX BX DX 425 MOV MOV LP_BEG: DX, [BP+0] BX, [BP+2] MOV AL, [BX] AL, [BP+4] LP_END WRITE_CHR DX, AL, AH JC EXIT INC BX JMP LP_BEG CMP JE LP_END: EXIT: MOV POP POP POP RET $WRITE_STR CODE [BP+4], AH DX CX AX 4 ENDP ENDS END TITLE PROGRAMMING ASSIGNMENT 12-1 PAGE 55, 80 COMMENT | PROGRAM : PA12-1.ASM PROGRAMMER : KADIR GECKIN DATE : 30/12/2000 DIZIN LISTESINI SAGLAYAN PROGRAM INPUT_STR, DSPLY_CHR, DSPLY_STR, DSPLY_IMMED_STR, DEFINE_DIR_BFR_STRUCT, SET_DTA, DIR_FRST AND DIR_NXT YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' DIR_BFR IO_BUF DATA DEFINE_DIR_BFR_STRUCT DIR_BUFFER <> DB 31 DUP ('*') ENDS 426 ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX, DATA DS, AX DS:DATA SET_DTA <OFFSET DIR_BFR> DSPLY_IMMED_STR <13,10, 'File(s) to search for?'> INPUT_STR <OFFSET IO_BUF>, 30 DSPLY_CHR 10 SUB CX, CX DIR_FRST <OFFSET IO_BUF>, , AL M_LP: JC M_LPEND INC CX DSPLY_STR <OFFSET DIR_BFR.ASCIIZ> DSPLY_IMMED_STR <13,10> DIR_NXT AL JMP M_LP M_LPEND: M_1: CMP JA CX, 0 M_1 DSPLY_IMMED_STR <10, 'File not found', 13,10> JMP SHORT DONE DSPLY_CHR 10 CNV_UNS_STR <OFFSET IO_BUF>,CX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <' matching files', 13, 10> DONE: RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 12-2 PAGE 55, 80 COMMENT | PROGRAM : PA12-2.ASM PROGRAMMER : KADIR GECKIN DATE : 30/12/2000 BIR DOSYANIN ISMINI DEGISTIREN PORGRAM INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR VE REN_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | 427 IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF1 IO_BUF2 EXPLAN DB DB DB DB DB DB DB DB DB ENDS DATA 31 DUP('*') 31 DUP('*') 13,10, 'Bothfile rename and new name' ' may include a drive and/or path.' 13, 10, 10 'The drives must agree.', 13, 10 'The path do not have to agree; you can' ' "move" a file between directoies' 13, 10, 0 ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX, DATA DS, AX DS:DATA DSPLY_STR <OFFSET EXPLAN> DSPLY_IMMED_STR <13,10, 'File to rename? '> INPUT_STR <OFFSET IO_BUF1>, 30 DSPLY_IMMED_STR <13, 10, 'New file name? '> INPUT_STR <OFFSET IO_BUF2>, 30 DSPLY_CHR 10 REN_FILE <OFFSET IO_BUF1>, <OFFSET IO_BUF2>, AL JC M_ERR DSPLY_IMMED_STR <'File renamed', 13, 10> JMP DONE M_ERR: C2_LBL: DSPLY_CHR 7 CMP AL, 02H JNE C2_LBL DSPLY_IMMED_STR <'File not found', 13, 10> JMP C_END CMP JNE AL, 03H C3_LBL DSPLY_IMMED_STR <'Path not found', 13, 10> JMP C_END 428 C3_LBL CMP JNE C4_LBL CMP JNE AL, 05H C4_LBL DSPLY_IMMED_STR <'Access denied (file', 13, 10> JMP SHORT C_END DSPLY_IMMED_STR <'already exist', 13, 10> JMP SHORT C_END AL, 11H C5_LBL DSPLY_IMMED_STR <'Not same dev,ce', 13, 10> JMP SHORT C_END DSPLY_IMMED_STR <10, 'Error: '> SUB AH, AH CNV_UNS_STR <OFFSET IO_BUF1>, AX, 16 DSPLY_STR <OFFSET IO_BUF1> DSPLY_IMMED_STR <'H',13, 10> C5_LBL: C_END: DONE: MAIN CODE ENDP ENDS END MAIN DONE: RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 12-3 PAGE 55, 80 COMMENT | PROGRAM : PA12-3.ASM PROGRAMMER : KADIR GECKIN DATE : 30/12/2000 BIR DOSYA SILEN PROGRAM INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR VE DEL_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') 429 STACK ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DB DATA ENDS 31 DUP('*') ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX, DATA DS, AX DS:DATA DSPLY_IMMED_STR <13,10, 'File to delete? '> INPUT_STR <OFFSET IO_BUF>, 30 DEL_FILE <OFFSET IO_BUF>, AL JC M_ERR DSPLY_IMMED_STR <'File deleted', 13, 10> JMP DONE M_ERR: DSPLY_CHR 7 CMP AL, 02H JNE C2_LBL DSPLY_IMMED_STR <'File not found', 13, 10> JMP C_END C2_LBL: CMP JNE AL, 03H C3_LBL DSPLY_IMMED_STR <'Path not found', 13, 10> JMP C_END C3_LBL CMP JNE AL, 05H C4_LBL DSPLY_IMMED_STR <'Access denied (file', 13, 10> JMP SHORT C_END C4_LBL: DSPLY_IMMED_STR <10, 'Error: '> SUB AH, AH CNV_UNS_STR <OFFSET IO_BUF>, AX, 16 DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <'H',13, 10> C_END: DONE: RET MAIN CODE ENDP ENDS END MAIN 430 TITLE PROGRAMMING ASSIGNMENT 12-4 PAGE 55, 80 COMMENT | PROGRAM : PA12-4.ASM PROGRAMMER : KADIR GECKIN DATE : 30/12/2000 KULLANICI TANIMLI KAYIT UZUNLUGU ILE BIR DOSYA KOPYALAYAN PROGRAM INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,OPEN_FILE, CREATE_FILE, READ_STREAM, WRITE_STREAM VE CLOSE_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF REC_BFR R_LEN I_HNDL O_HNDL DB DB DW DW DW DATA ENDS 4 DUP ('I/O BFR') 32 DUP('RECORD BUFFER***') ? ? ? ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX, DATA DS, AX DS:DATA LP_1: DSPLY_IMMED_STR <13, 10, 10, 'Rec len to'> DSPLY_IMMED_STR 'use on copy (1 - 512)?' 431 C_1: LP_END: INPUT_STR <OFFSET IO_BUF>, 3 CNV_STR_UNS <OFFSET IO_BUF>, AX JC C_1 CMP AX, 512 JA C_1 CMP AX, 0 JA LP1_END DSPLY_IMMED_STR <7, 'Invalid lenght; '> DSPLY_IMMED_STR 'try again' JMP LP_1 MOV R_LEN, AX LP_2: DSPLY_IMMED_STR <13, 10, 10,'File to copy '> DSPLY_IMMED_STR 'from (Input)?' INPUT_STR <OFFSET IO_BUF>, 31 OPEN_FILE <OFFSET IO_BUF>, R, BX, AL JNC LP_2_END DSPLY_IMMED_STR <7, 'Bad input file name; '> DSPLY_IMMED_STR 'try again.' JMP LP_2 LP2_END: MOV I_HNDL, BX LP_3: DSPLY_IMMED_STR <13, 10, 10, 'File to copy '> DSPLY_IMMED_STR 'to (Output)? ' INPUT_STR <OFFSET IO_BUF>, 31 CREATE_FILE <OFFSET IO_BUF>, , BX, AL JNC LP3_END DSPLY_IMMED_STR <7, 'Bad output file name; '> DSPLY_IMMED_STR 'try again' JMP LP_3 LP3_END: MOV O_HNDL, BX MOV CX, 0 DSPLY_IMMED_STR <'Copying the file',13, 10> LP_4: MOV AX, I_HNDL MOV BX, R_LEN READ_STREAM AX, BX, <OFFSET REC_BFR> JC CMP JE LP4_END BX, 0 LP4_END MOV AX, OHNDL WRITE_STREAM AX, BX, <OFFSET REC_BFR> JC LP4_END CMP BX, 0 JE LP4_END MOV AX, OHNDL WRITE_STREAM AX,BX, <OFFSET REC_BFR> JC LP4_END INC CX CMP R_LEN, BX JA LP4_END JMP LP_4 LP4_END: JNC CPY_OK CMP JNE AX, I_HNDL WRT_ERR DSPLY_IMMED_STR <7, 'Error reading '> DSPLY_IMMED_STR 'input file.' JMP DONE 432 WRT_ERR: DSPLY_IMMED_STR <7, 'Error writing to '> DSPLY_IMMED_STR 'output file.' JMP DONE CPY_OK: DSPLY_IMMED_STR CNV_UNS_STR DSPLY_STR DSPLY_IMMED_STR DONE: MOV AX,I_HNDL CLOSE_FILE AX JNC CLS1_OK DSPL_IMMED_STR 'Unable to close input ' DSPL_IMMED_STR <'file', 13, 10> MOV AX, O_HNDL CLOSE_FILE AX JNC CLS2_OK DSPL_IMMED_STR 'Unable to close output ' DSPL_IMMED_STR <'file',13,10> CLS1_OK: <10, 10, 'Copy complete -'> <OFFSET IO_BUF>, CX <OFFSET IO_BUF> <' records copied.', 13, 10> CLS2_OK: RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 12-5 PAGE 55, 80 COMMENT | PROGRAM : PA12-5.ASM PROGRAMMER : KADIR GECKIN DATE : 30/12/2000 BIR OKUYUSLA VE BIR YAZISLA DOSYA KOPYALAYAN PROGRAM (DOSYA ASAGI YUKARI 32768 BYTE'TAN BUYUK) INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,OPEN_FILE, CREATE_FILE,SEEK, READ_STREAM, WRITE_STREAM VE CLOSE_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' 433 DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF REC_BFR I_HNDL O_HNDL DB DB DW DW DATA ENDS 4 DUP ('I/O BFR') 32368 DUP('*') ? ? ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX, DATA DS, AX DS:DATA LP_1: LP1_END: DSPLY_IMMED_STR <13, 10, 10, 'File to copy'> DSPLY_IMMED_STR 'from (Input)?' INPUT_STR <OFFSET IO_BUF>, 31 OPEN FILE <OFFSET IO_BUF>, R, AX JNC LP1_END DSPLY_IMMED_STR <7, 'Bad input file name;'> DSPLY_IMMED_STR 'try again.' JMP LP_1 MOV I_HNDL, AX SUB BX, BX MOV CX, BX SEEK AX, END, BX, CX JNC C_1: C_2: C_3: C_1 DSPLY_IMMED_STR 'Error seeking end of file ' DSPLY_IMMED_STR <13, 10> JMP DONE CMP BX, 0 JA C_2 CMP CX, 32768 JBE C_3 DSPLY_IMMED_STR 'File too big (GT 32768 ' DSPLY_IMMED_STR <'bytes)', 13, 10> JMP DONE SEEK AX, BEG, BX, BX JNC C_4 DSPLY_IMMED_STR 'Error seeking begining ' DSPLY_IMMED_STR <'of file', 13, 10> JMP DONE C_4: LP_2: DSPLY_IMMED_STR <13, 10, 10, 'File to copy'> 434 DSPLY_IMMED_STR 'to (Output)? ' INPUT_STR <OFFSET IO_BUF>, 31 CREATE_FILE <OFFSET IO_BUF>, , AX JNC LP2_END DSPLY_IMMED_STR <7, 'Bad output file name; '> DSPLY_IMMED_STR 'try again.' JMP LP_2 LP2_END: C_5: MOV O_HNDL, AX DSPLY_IMMED_STR <'Copying the file', 13, 10> MOV AX, I_HNDL READ_STREAM AX, CX, <OFFSET REC_BFR> JNC C_5 DSPLY_IMMED_STR 'Error reading input ' DSPLY_IMMED_STR <'file', 13, 10> JMP DONE MOV AX, O_HNDL WRITE_STREAM AX, CX, <OFFSET REC_BFR> JNC C_6 DSPLY_IMMED_STR 'Error writing to output' DSPLY_IMMED_STR <'file',13, 10> JMP DONE C_6: DSPLY_IMMED_STR CNV_UNS_STR DSPLY_STR DSPLY_IMMED_STR <10, 10, 'Copy complete - '> <OFFSET IO_BUF>, CX <OFFSET IO_BUF> <' bytes copied.', 13,10> DONE: MOV JNC C_7: MOV AX, O_HNDL CLOSE_FILE AX JNC C_8 DSPLY_IMMED_STR 'Unable to close output ' DSPLY_IMMED_STR <'file', 13, 10> AX, I_HNDL C_7 DSPLY_IMMED_STR 'Unable to close input ' DSPLY_IMMED_STR <'file', 13, 10> C_8: RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 12-6 PAGE 55, 80 COMMENT | PROGRAM : PA12-6.ASM PROGRAMMER : KADIR GECKIN DATE : 31/12/2000 KLAVYEDEN DOSYAYA KOPYALAYAN PROGRAM, SONRA GERI DONER (DOSYANIN BASLANGICINI ARAR) VE KAPATMADAN ONCE GOSTERIR. INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,SET_DTA,DEFINE_DIR_BFR_STRUCT, DIR_FRST, CREATE_FILE, READ_STREAM, WRITE_STREAM, SEEK VE CLOSE_FILE YAPITASLARI KULLANILIR. 435 INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF DEFINE_DIR_BFR_STRUCT ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF REC_BFR DIR_BFR F_NAME DB 4 DUP ('I/O BFR') DB '*' DIR_BUFFER <> DB 'A:KEYBOARD.DAT', 0 DATA ENDS ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX, DATA DS, AX DS:DATA SET_DTA <OFFSET DIR_BFR> DIR_FRST <OFFSET F_NAME>, , AL JC C_2 DSPLY_IMMED_STR <7, 'A:KEYBOARD.DAT exist '> DSPLY_IMMED_STR ' - Replace (Y or N)?' INPUT_STR <OFFSET IO_BUF>, 1 AND IO_BUF, 255-32 CMP IO_BUF, 'Y' JE C_1 DSPLY_IMMED_STR <'Aborting program', 13, 10> JMP M_RET C_1: C_2: C_3: CREATE_FILE <OFFSET F_NAME>, , BX DSPLY_IMMED_STR <7, 'Unable to create A:'> DSPLY_IMMED_STR <'KEYBOARD.DAT',13,10> JMP M_RET DSPLY_IMMED_STR <10, 'Copying keyboard to A:'> DSPLY_IMMED_STR <'KEYBOARD.DAT',13,10, 'Type '> 436 DSPLY_IMMED_STR <'<Ctrl>+<Z> to stop:',13,10,10> SUB CX, CX LP1_BEG: INPUT_CHR AL JC C_5 CMP AL, 26 JE LP1_END CALL ONE_CHAR JNC C_4 DSPLY_IMMED_STR <7, 'Error writing to '> DSPLY_IMMED_STR <'file',13,10> JMP DONE C_4: CMP JNE C_5: JMP AL, 13 C_5 MOV AL, 10 CALL ONE_CHAR LP_1BEG LP1_END: DSPLY_IMMED_STR <'^Z', 13, 10, 10> CNV_UNS_STR <OFFSET IO_BUF>, CX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <' characters in file:', 13, 10> SUB AX ,AX SEEK BX, BEG, AX, AX JNC C_6 DSPLY_IMMED_STR <7, 'Error seeking begining'> DSPLY_IMMED_STR <' of file',13 ,10> JMP DONE C_6: M_LP2: MOV AX, 1 READ_STREAM BX, AX, <OFFSET REC_BUF> JNC C_7 DSPLY_IMMED_STR <7, 'Error reading '> DSPLY_IMMED_STR <'form file',13, 10> JMP SHORT DONE C_7: MOV AL, REC_BUF DSPLY_CHR AL LOOP M_LP2 DONE: CLOSE_FILE BX JNC C_8 DSPLY_IMMED_STR <7, 'Unable to close file'> DSPLY_IMMED_STR <13, 10> C_8: M_RET: MAIN RET ENDP ONE_CHAR PROC NEAR PUSH AX DSPLY_CHR AL MOV REC_BUF, AL MOV AX, 1 437 WRITE_STREAM INC CX POP BX, AX, <OFFSET REC_BUF> AX RET ONE_CHAR ENDP CODE ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 12-7 PAGE 55, 80 COMMENT | PROGRAM : PA12-7.ASM PROGRAMMER : KADIR GECKIN DATE : 31/12/2000 A:CUSTOMER.DAT ICINDE SAPLAYAN PROGRAM MUSTERI ISIM LISTESINE DOGRUDAN ERISIMI INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,OPEN_FILE, CREATE_FILE, ,RSEEK, READ_STREAM, WRITE_STREAM VE CLOSE_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF REC_BFR DB DB DB DB DB DB DB DB DB DB DB DB F_NAME WARNING MENU 4 DUP ('I/O BFR') 24 DUP ('*') 0 'A:KEYBOARD.DAT', 0 13, 10, 10, 10, 'WARNING: Viewing a ' ' record which has not yet been written ' ' to the file', 13, 10 ' may display "garbage" data.' 13, 10, 0 13, 10, 10, 'Your options are:'. 13, 10 ' V View a customer', 13, 10 ' W Write a customer', 13, 10 438 V_CNT W_CNT DB DB DW DW ' Q Quit to DOS', 13, 10 'Enter your choice>', 0 0 0 DATA ENDS ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX, DATA DS, AX DS:DATA JC JMP C_1: C_2: C_3: C_1 C_5 CMP JE AL, 02H C_2 DSPLY_IMMED_STR 'Error opening customer ' DSPLY_IMMED_STR 'file - ' CALL DSP_ERR JMP M_RET DSPLY_IMMED_STR <7, 'Customer file not found'> DSPLY_IMMED_STR '- Create it (Y or N)' INPUT_STR <OFFSET IO_BUF> INPUT_STR <OFFSET IO_BUF>,1 AND BYTE PTR IO_BUF, 0DFH CMP BYTE PTR IO_BUF, 'Y' JE C_3 DSPLY_IMMED_STR <'Aborting program',13,10> JMP M_RET CREATE_FILE <OFFSET F_NAME>, , BX, AL JNC C_4 DSPLY_IMMED_STR 'Error creating customer ' DSPLY_IMMED_STR 'file - ' CALL DSP_ERR JMP M_RET C_4: C_5: DSPLY_STR LP_BEG: C2_LBL: <OFFSET WARNING> DSPLY_STR <OFFSET MENU> INPUT_STR <OFFSET IO_BUF>, 1 MOV AL, IO_BUF AND AL, ODFH CMP AL, 'Q' JE LP_END CMP AL, 'Q' JNE C2_LBL CALL VIEW JMP SHORT C_END CMP AL, 'W' JNE C_ELSE CALL WRITE 439 C_ELSE: DSPLY_IMMED_STR <7, 'Invalid option'> DSPLY_IMMED_STR <13, 10, 10> C_END: JMP LP_BEG LP_END: CLOSE_FILE BX JNC C_6 DSPLY_IMMED_STR <7, Unable to close '> DSPLY_IMMED_STR <' file', 13, 10> C_6: DSPLY_IMMED_STR <13, 10, 10> MOV AX, V_CNT CNV_UNS_STR <OFFSET IO_BUF>, AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <' customers viewed.', 13, 10> MOV AX, W_NCT CNV_UNS_STR <OFFSET IO_BUF>, AX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <' customer writtten.',13, 10> M_RET: RET MAIN ENDP ;---------------------------------------------------------------------VIEW PROC NEAR PUSH AX PUSH CX CALL SEEK_REC MOV CX, 24 READ_STREAM BX, CX, <OFFSET REC_BUF>, AL JC CMP JE V_1 CX, 24 V_2 SUB AL, AL V_1: DSPLY_IMMED_STR 'Error reading customer ' DSPLY_IMMED_STR 'file - ' CALL DSP_ERR JMP SHORT V_3 V_2: DSPLY_IMMED_STR 'Customer name:' DSPLY_STR <OFFSET REC_BUF> INC V_CNT V_3: POP POP RET VIEW ENDP CX AX ;-----------------------------------------------------------------------WRITE PROC NEAR PUSH PUSH CALL JNC AX CX SEEK_REC W_1 440 DSPLY_IMMED_STR 'Error seeking record - ' CALL DSP_ERR JMP W_4 W_1: DSPLY_IMMED_STR 'Customer name: ' INPUT_STR <OFFSET REC_BUF>, 24 MOV CX, 24 WRITE_STREAM BX, CX, <OFFSET REC_BUF>, AL JNC W_2 DSPLY_IMMED_STR 'Error writing record - ' CALL DSP_ERR JMP SHORT W_3 W_2: DSPLY_STR <OFFSET REC_BUF> DSPLY_IMMED_STR ' added to the file.' DSPLY_IMMED_STR <13, 10> INC W_CNT W_3: W_4: WRITE POP POP RET CX AX ENDP ;-----------------------------------------------------------------------SEEK SRLP_BEG: PROC NEAR PUSH AX DSPLY_IMMED_STR 'Customer number (>=1)? ' INPUT_STR <OFFSET IO_BUF>, 5 CNV_STR_UNS <OFFSET IO_BUF>, AX JC SUB JNC SR_1: SRLP_END: SEEK_REC SR_1 AX, 1 SRLP_END DSPLY_IMMED_STR <7, Invalid - Try again.'> DSPLY_IMMED_STR <13, 10, 10> JMP SRLP_BEG RSEEK BX, BEG, 24, AX POP AX RET ENDP ;---------------------------------------------------------------------DSP_ERR PROC NEAR PUSH AX DSPLY_CHR 7 CMP AL, 0 JNE DE_1 DSPLY_IMMED_STR <'End of file.', 13, 10> JMP DE_END DE_1: CMP JNE AL, 03H DE_2 DSPLY_IMMED_STR <'Path not found.',13,10> JMP DE_END 441 DE_2: CMP JNE AL, 04H DE_3 DSPLY_IMMED_STR <'Too many open files.'> DSPLY_IMMED_STR <13,10> JMP DE_END DE_3: CMP JNE AL, 05H DE_4 DSPLY_IMMED_STR <'Access denied.', 13, 10> DSPLY_IMMED_STR <13,10> JMP DE_END DE_4: CMP JNE AL, 0FH DE_5 DSPLY_IMMED_STR <'Invalid drive.', 13, 10> JMP DE_END DE_5: CMP JNE AL, 13H DE_6 DSPLY_IMMED_STR <'Disk write protected.'> DSPLY_IMMED_STR <13,10> JMP DE_END DE_6: CMP JNE AL, 15H DE_7 DSPLY_IMMED_STR <'Drive not ready.',13,10> JMP DE_END DE_7: CMP JNE AL, 17H DE_8 DSPLY_IMMED_STR <'Data error (bad CRC).'> DSPLY_IMMED_STR <13,10> JMP DE_END DE_8: CMP JNE AL, 17H DE_9 DSPLY_IMMED_STR <'Seek error.', 13, 10> JMP DE_END DE_9: CMP JNE AL, 1BH DE_10 DSPLY_IMMED_STR <'Sector not found.'> DSPLY_IMMED_STR <13,10> JMP DE_END DE_10: SUB AL, AH CNV_UNS_STR <OFFSET IO_BUF>,AX, 16 DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <'H', 13, 10> DE_END: POP RET DSP_ERR CODE ENDP ENDS END MAIN AX TITLE PROGRAMMING ASSIGNMENT 12-8 PAGE 55, 80 442 COMMENT | PROGRAM : PA12-8.ASM PROGRAMMER : KADIR GECKIN DATE : 31/12/2000 TERMINAL- FORMATLI DOSYAYA CIZGI CIZGI OKUYUP GOSTEREN PROGRAM INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,OPEN_FILE, READ_STR VE CLOSE_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF TRUNC_MSG DB DB DB DB DATA ENDS 10 DUP ('I/O BFR') '*' 7, '**** Next line too long - It has been' 'truncated****',13, 10, 0 ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX, DATA DS, AX DS:DATA LP_1_BEG: LP1_END: DSPLY_IMMED_STR <13, 10, 10> DSPLY_IMMED_STR ' File to display?' INPUT_STR <OFFSET IO_BUF>, 31 OPEN_FILE <OFFSET IO_BUF>, R, BX JNC LP1_END DSPLY_IMMED_STR <7, Bad filename; try again.> JMP LP1_BEG DSPLY_IMMED_STR <13, 10, 10> READ_STR BX, <OFFSET IO_BUF>, 80, , AL 443 JNC CMP JE C_1: C_2 AL, 0 LP_2_END CMP AL, 8 JNE C_1 DSPLY_STR <OFFSET TRUNC_MSG> JMP SHORT C_2 DSPLY_IMMED_STR <7, 'Unable to read file'> DSPLY_IMMED_STR <13, 10> DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <13, 10, '*** Press any key***'> INPUT_CHR JMP LP2_BEG LP2_END: CLOSE_FILE BX JNC C_3 DSPLY_IMMED_STR 'Unable to close input ' DSPLY_IMMED_STR <'file', 13, 10> C_3: RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 12-9 PAGE 55, 80 COMMENT | PROGRAM : PA12-9.ASM PROGRAMMER : KADIR GECKIN DATE : 31/12/2000 TEMINAL-FORMATLI DOSYAYA BIR ANDA BIR KARAKTER KOPYALAYAN PROGRAM, KARAKTERLERI SAYMA INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,OPEN_FILE, CREATE_FILE, READ_CHR, WRITE_CHR VE CLOSE_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS 444 ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DB DATA ENDS 4 DUP ('I/O BFR') ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX, DATA DS, AX DS:DATA LP1_BEG: DSPLY_IMMED_STR <13, 10, 10, 'File to copy '> DSPLY_IMMED_STR 'from (Input)?' INPUT_STR <OFFSET IO_BUF>, 31 OPEN_FILE <OFFSET IO_BUF>, R, BX, AL JNC LP1_END DSPLY_IMMED_STR <7, 'Bad input file name;'> DSPLY_IMMED_STR 'try again.' JMP LP1_BEG LP1_END: LP2_BEG: DSPLY_IMMED_STR <13, 10, 10, 'File to copy '> DSPLY_IMMED_STR 'to (Output)?' INPUT_STR <OFFSET IO_BUF>, 31 CREATE_FILE <OFFSET IO_BUF>, DX, AL JNC LP2_END DSPLY_IMMED_STR <7, 'Bad output file name;'> DSPLY_IMMED_STR 'try again.' JMP LP2_BEG LP2_END: LP3_BEG: READ_CHR BX, AL JNC C_2 CMP AL, 0 JNE C_1 DSPLY_IMMED_STR <7, 'No error.', 13, 10> DSPLY_IMMED_STR <13, 10> MOV AL, 26 JMP SHORT C_2 C_1: DSPLY_IMMED_STR <7, 'Read error.',13, 10> JMP LP3_END C_2: WRITE_CHR DX, AL JNC C_3 DSPLY_IMMED_STR <7, 'Write error.', 13, 10> JMP LP3_END C_3: CMP CMP INC CX AL, 26 LP3_BEG 445 LP3_END: DSPLY_IMMED_STR <'Copy complete - '> CNV_UNS_STR <OFFSET IO_BUF>, CX DSPLY_STR <OFFSET IO_BUF>, DSPLY_IMMED_STR <' character copied.',13,10> CLOSE_FILE BX JNC C_4 DSPLY_IMMED_STR 'Unable to close output ' DSPLY_IMMED_STR <'file', 13, 10> C_4: CLOSE_FILE DX JNC C_5 DSPLY_IMMED_STR 'Unable to close output ' DSPLY_IMMED_STR <'file',13, 10> C_5: RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 12-10 PAGE 55, 80 COMMENT | PROGRAM : PA12-10.ASM PROGRAMMER : KADIR GECKIN DATE : 31/12/2000 TEMINAL-FORMATLI DOSYAYA PROGRAM, CIZGILERI SAYMA BIR ANDA BIR CIZGI KOPYALAYAN INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,OPEN_FILE, CREATE_FILE, READ_STR, WRITE_STR VE CLOSE_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF DB DB 10 0 DUP ('I/O BFR') 446 IO_BUF2 DATA DB ENDS 6 DUP('*') ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX, DATA DS, AX DS:DATA LP1_BEG: DSPLY_IMMED_STR <13, 10, 10, 'File to copy '> DSPLY_IMMED_STR 'from (Input)?' INPUT_STR <OFFSET IO_BUF>, 31 OPEN_FILE <OFFSET IO_BUF>, R, BX, AL JNC LP1_END DSPLY_IMMED_STR <7, 'Bad input file name;'> DSPLY_IMMED_STR 'try again.' JMP LP1_BEG LP1_END: LP2_BEG: DSPLY_IMMED_STR <13, 10, 10, 'File to copy '> DSPLY_IMMED_STR 'to (Output)?' INPUT_STR <OFFSET IO_BUF>, 31 CREATE_FILE <OFFSET IO_BUF> JNC LP2_END DSPLY_IMMED_STR <7, 'Bad output file name;'> DSPLY_IMMED_STR 'try again.' JMP LP2_BEG LP2_END: MOV CX, 0 DSPLY_IMMED_STR <'Copying the file', 13, 10, 10> LP3_BEG: READ_STR BX, <OFFSET IO_BUF>, 80, AL JNC C_2 CMP AL, 0 JNE C_0 JMP LP3_END C_0: CMP JNE C_1: DSPLY_IMMED_STR <7, 'Read error.',13, 10> JMP LP3_END C_2: AL, 8 C_1 DSPLY_IMMED_STR <7, 'Line '> CNV_UNS_STR <OFFSET IO_BUF2>, CX DSPLY_STR <OFFSET IO_BUF2> DSPLY_IMMED_STR ' too long - truncated' DSPLY_IMMED_STR <13,10> JMP SHORT C_2 WRITE_STR DX, <OFFSET IO_BUF>, , AL WRITE_IMMED_STR DX, <13, 10>, , AL JNC C_3 DSPLY_IMMED_STR <7, 'Write error.', 13, 10> 447 JMP C_3: CMP LP3_END INC CX LP3_BEG LP3_END: WRITE_CHR DX, 26 DSPLY_IMMED_STR <'Copy complete - '> CNV_UNS_STR <OFFSET IO_BUF>, CX DSPLY_STR <OFFSET IO_BUF>, DSPLY_IMMED_STR <' lines copied.',13,10> CLOSE_FILE BX JNC C_4 DSPLY_IMMED_STR 'Unable to close input file ' DSPLY_IMMED_STR <13, 10> C_4: WRITE_CHR DX, 26 CLOSE_FILE DX JNC C_5 DSPLY_IMMED_STR 'Unable to close output file ' DSPLY_IMMED_STR <13, 10> C_5: RET MAIN CODE ENDP ENDS END MAIN ASSEMBLY PROGRAM ÖRNEKLERİ 448 BÖLÜM-8: TITLE PROGRAMMING ASSIGNMENT 13-1 PAGE 55, 80 COMMENT | PROGRAM : PA13-1.ASM PROGRAMMER : KADIR GECKIN DATE : 31/12/2000 BIR DOSYANIN ISMINI DEGISTIREN PROGRAM ******* MUST USE EXE2BIN TO CONVERT TO A COM FILE ******* INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR VE REN_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF P_GROUP GROUP ASSUME DATA, CODE CS:P_GROUP, DS:P_GROUP, ES:P_GROUP ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' ENTRY: ORG JMP IO_BUF1 IO_BUF2 EXPLAN DATA DB DB DB DB DB DB DB DB DB ENDS 100H NEAR PTR MAIN 31 DUP('*') 31 DUP('*') 13,10, 'Bothfile rename and new name' ' may include a drive and/or path.' 13, 10, 10 'The drives must agree.', 13, 10 'The path do not have to agree; you can' ' "move" a file between directoies' 13, 10, 0 ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' MAIN PROC FAR DSPLY_STR <OFFSET EXPLAN> DSPLY_IMMED_STR <13,10, 'File INPUT_STR <OFFSET IO_BUF1>, DSPLY_IMMED_STR <13, 10, 'New INPUT_STR <OFFSET IO_BUF2>, DSPLY_CHR 10 449 to rename? '> 30 file name? '> 30 REN_FILE <OFFSET IO_BUF1>, <OFFSET IO_BUF2>, AL JC M_ERR DSPLY_IMMED_STR <'File renamed', 13, 10> JMP DONE M_ERR: DSPLY_CHR 7 CMP AL, 02H JNE C2_LBL DSPLY_IMMED_STR <'File not found', 13, 10> JMP C_END C2_LBL: CMP JNE AL, 03H C3_LBL DSPLY_IMMED_STR <'Path not found', 13, 10> JMP C_END C3_LBL CMP JNE AL, 05H C4_LBL DSPLY_IMMED_STR <'Access denied (file', 13, 10> JMP SHORT C_END DSPLY_IMMED_STR <'already exist', 13, 10> JMP SHORT C_END C4_LBL CMP JNE AL, 11H C5_LBL DSPLY_IMMED_STR <'Not same dev,ce', 13, 10> JMP SHORT C_END DSPLY_IMMED_STR <10, 'Error: '> SUB AH, AH CNV_UNS_STR <OFFSET IO_BUF1>, AX, 16 DSPLY_STR <OFFSET IO_BUF1> DSPLY_IMMED_STR <'H',13, 10> C5_LBL: C_END: DONE: INT 20H MAIN CODE ENDP ENDS END DONE: RET MAIN CODE ENDP ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 13-2 PAGE 55, 80 COMMENT | PROGRAM : PA13-2.ASM PROGRAMMER : KADIR GECKIN DATE : 31/12/2000 KULLANICI TANIMLI KAYIT UZUNLUGU ILE BIR DOSYA KOPYALAYAN PROGRAM 450 ******* MUST USE EXE2BIN TO CONVERT TO A COM FILE ******* INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,OPEN_FILE, CREATE_FILE, READ_STREAM, WRITE_STREAM VE CLOSE_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF P_GROUP GROUP ASSUME DATA, CODE CS:P_GROUP, DS:P_GROUP, ES:P_GROUP ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF REC_BFR R_LEN I_HNDL O_HNDL DB DB DW DW DW DATA ENDS 4 DUP ('I/O BFR') 32 DUP('RECORD BUFFER***') ? ? ? ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' MAIN PROC LP_1: C_1: LP_END: FAR DSPLY_IMMED_STR <13, 10, 10> DSPLY_IMMED_STR 'Rec len to use on copy ' DSPLY_IMMED_STR '(1 - 512)?' INPUT_STR <OFFSET IO_BUF>, 3 CNV_STR_UNS <OFFSET IO_BUF>, AX JC C_1 CMP AX, 512 JA C_1 CMP AX, 0 JA LP1_END DSPLY_IMMED_STR <7, 'Invalid lenght; '> DSPLY_IMMED_STR 'try again' JMP LP_1 MOV R_LEN, AX LP_2: DSPLY_IMMED_STR <13, 10, 10,'File to copy '> DSPLY_IMMED_STR 'from (Input)?' INPUT_STR <OFFSET IO_BUF>, 31 OPEN_FILE <OFFSET IO_BUF>, R, BX, AL JNC LP_2_END DSPLY_IMMED_STR <7, 'Bad input file name; '> DSPLY_IMMED_STR 'try again.' JMP LP_2 LP2_END: MOV I_HNDL, BX 451 LP_3: DSPLY_IMMED_STR <13, 10, 10, 'File to copy '> DSPLY_IMMED_STR 'to (Output)? ' INPUT_STR <OFFSET IO_BUF>, 31 CREATE_FILE <OFFSET IO_BUF>, , BX, AL JNC LP3_END DSPLY_IMMED_STR <7, 'Bad output file name; '> DSPLY_IMMED_STR 'try again' JMP LP_3 LP3_END: MOV O_HNDL, BX MOV CX, 0 DSPLY_IMMED_STR <'Copying the file',13, 10> LP_4: MOV AX, I_HNDL MOV BX, R_LEN READ_STREAM AX, BX, <OFFSET REC_BFR> JC CMP JE LP4_END BX, 0 LP4_END MOV AX, OHNDL WRITE_STREAM AX, BX, <OFFSET REC_BFR> JC LP4_END INC CX CMP R_LEN, BX JA LP4_END JMP LP_4 LP4_END: JNC CPY_OK CMP JNE AX, I_HNDL WRT_ERR DSPLY_IMMED_STR <7, 'Error reading '> DSPLY_IMMED_STR 'input file.' JMP DONE WRT_ERR: DSPLY_IMMED_STR <7, 'Error writing to '> DSPLY_IMMED_STR 'output file.' JMP DONE CPY_OK: DSPLY_IMMED_STR CNV_UNS_STR DSPLY_STR DSPLY_IMMED_STR DONE: MOV AX,I_HNDL CLOSE_FILE AX JNC CLS1_OK DSPL_IMMED_STR 'Unable to close input ' DSPL_IMMED_STR <'file', 13, 10> MOV AX, O_HNDL CLOSE_FILE AX JNC CLS1_OK DSPL_IMMED_STR 'Unable to close output ' DSPL_IMMED_STR <'file',13,10> CLS1_OK: <10, 10, 'Copy complete -'> <OFFSET IO_BUF>, CX <OFFSET IO_BUF> <' records copied.', 13, 10> CLS2_OK: INT MAIN CODE ENDP ENDS END 20H ENTRY 452 TITLE PROGRAMMING ASSIGNMENT 13-3 PAGE 55, 80 COMMENT | PROGRAM : PA13-3.ASM PROGRAMMER : KADIR GECKIN DATE : 31/12/2000 KULLANICI TANIMLI KAYIT UZUNLUGU ILE BIR DOSYA KOPYALAYAN PROGRAM ******* MUST USE EXE2BIN TO CONVERT TO A COM FILE ******* INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,OPEN_FILE, CREATE_FILE,SEEK, READ_STREAM, WRITE_STREAM VE CLOSE_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF P_GROUP GROUP ASSUME DATA, CODE CS:P_GROUP, DS:P_GROUP, ES:P_GROUP ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF REC_BFR I_HNDL O_HNDL DB DB DW DW DATA ENDS 4 DUP ('I/O BFR') 32368 DUP('*') ? ? ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' MAIN PROC LP_1: LP1_END: FAR DSPLY_IMMED_STR <13, 10, 10, 'File to copy'> DSPLY_IMMED_STR 'from (Input)?' INPUT_STR <OFFSET IO_BUF>, 31 OPEN FILE <OFFSET IO_BUF>, R, AX JNC LP1_END DSPLY_IMMED_STR <7, 'Bad input file name;'> DSPLY_IMMED_STR 'try again.' JMP LP_1 MOV I_HNDL, AX SUB BX, BX MOV CX, BX SEEK AX, END, BX, CX 453 JNC C_1: C_2: C_3: C_1 DSPLY_IMMED_STR 'Error seeking end of file ' DSPLY_IMMED_STR <13, 10> JMP DONE CMP BX, 0 JA C_2 CMP CX, 32768 JBE C_3 DSPLY_IMMED_STR 'File too big (GT 32768 ' DSPLY_IMMED_STR <'bytes)', 13, 10> JMP DONE SEEK AX, BEG, BX, BX JNC C_4 DSPLY_IMMED_STR 'Error seeking begining ' DSPLY_IMMED_STR <'of file', 13, 10> JMP DONE C_4: LP_2: DSPLY_IMMED_STR <13, 10, 10, 'File to copy'> DSPLY_IMMED_STR 'to (Output)? ' INPUT_STR <OFFSET IO_BUF>, 31 CREATE_FILE <OFFSET IO_BUF>, , AX JNC LP2_END DSPLY_IMMED_STR <7, 'Bad output file name; '> DSPLY_IMMED_STR 'try again.' JMP LP_2 LP2_END: C_5: MOV O_HNDL, AX DSPLY_IMMED_STR <'Copying the file', 13, 10> MOV AX, I_HNDL READ_STREAM AX, CX, <OFFSET REC_BFR> JNC C_5 DSPLY_IMMED_STR 'Error reading input ' DSPLY_IMMED_STR <'file', 13, 10> JMP DONE MOV AX, O_HNDL WRITE_STREAM AX, CX, <OFFSET REC_BFR> JNC C_6 DSPLY_IMMED_STR 'Error writing to output' DSPLY_IMMED_STR <'file',13, 10> JMP DONE C_6: DSPLY_IMMED_STR CNV_UNS_STR DSPLY_STR DSPLY_IMMED_STR <10, 10, 'Copy complete - '> <OFFSET IO_BUF>, CX <OFFSET IO_BUF> <' bytes copied.', 13,10> DONE: MOV AX, I_HNDL CLOSE_FILE AX JNC C_7 DSPLY_IMMED_STR 'Unable to close input file ' DSPLY_IMMED_STR <13, 10> C_7: MOV AX, O_HNDL CLOSE_FILE AX JNC C_8 DSPLY_IMMED_STR 'Unable to close output file ' DSPLY_IMMED_STR <13, 10> C_8: INT 20 454 MAIN CODE ENDP ENDS END ENTRY TITLE PROGRAMMING ASSIGNMENT 13-4 PAGE 55, 80 COMMENT | PROGRAM : PA13-4.ASM PROGRAMMER : KADIR GECKIN DATE : 31/12/2000 BIR DOSYANIN ISMINI DEGISTIREN PROGRAM, DOSYA ISIMLERINI DOS'UN KOMUT SATIRINDAN ALIR. INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,REN_FILE, YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;PSP SEGMENT OUTSIDE PROGRAM (AT COMBINE TYPE) ===================== PSP_SEG SEGMENT AT 0 INT_20_INST RSV_1 DOS_CALL_INST TERM_ADD BREAK_ADD ERROR_ADD RSV_2 ENV_SEG_ADD DB DB DB DB DD DD DB DW ?, ? ? 5 DUP (?) ? ? ? 22 DUP (?) ? RSV_3 FUNCT_DISP PARAM_1 PARAM_2 CMD_LEN CMD_LINE DEF_DTA DB DW DB DB DB DB ORG DB 34 DUP (?) 6 DUP (?) 16 DUP (?) 20 DUP (?) ? 127 DUP (?) 80H 128 DUP (?) PSP_SEG ENDS ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT =================================================== 455 DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF1 IO_BUF2 DB DB DATA ENDS 31 DUP('*') 31 DUP('*') ;CODE SEGMENT =================================================== CODE MAIN SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK, ES:PSP_SEG PROC NEAR PUSH MOV PUSH MOV MOV ASSUME DS AX, AX AX, DS, DS: MOV SUB MOV CALL MOV CALL CL, CMD_LEN SI, OFFSET CMD_LINE DI, OFFSET IO_BUF1 COPY_PRM DI, OFFSET IO_BUF2 COPY_PRM 0 DATA AX DATA REN_FILE <OFFSET IO_BUF>, <OFFSET IO_BUF2>, AL JC M_ERR DSPLY_IMMED_STR <'File renamed', 13,10> DSPLY_IMMED_STR <13, 10> JMP DONE M_ERR: DSPLY_CHR CMP JNE 7 AL, 02H C2_LBL DSPLY_IMMED_STR 'File not found' DSPLY_IMMED_STR <13,10> JMP C_END C2_LBL: CMP JNE AL, 03H C3_LBL DSPLY_IMMED_STR 'Path not found' DSPLY_IMMED_STR <13, 10> JMP C_END C3_LBL: CMP JNE AL, 05H C4_LBL DSPLY_IMMED_STR 'Access denied (file' DSPLY_IMMED_STR 'already exist)' DSPLY_IMMED_STR <13, 10> JMP SHORT C_END C4_LBL: CMP JNE AL, 11H C5_LBL DSPLY_IMMED_STR 'Not same device' DSPLY_IMMED_STR <13, 10> JMP SHORT C_END 456 C5_LBL: DSPLY_IMMED_STR <10, 'Error: '> SUB AH, AH CNV_UNS_STR <OFFSET IO_BUF1>, AX, 16 DSPLY_STR <OFFSET IO_BUF1> DSPLY_IMMED_STR <'H',13, 10> C_END: DONE: RET MAIN ENDP ;COPY_PRM ---------------------------------------------------------------COPY_PRM CP_LP1: CP_LP1_RPT: CP_LP1_END: PROC NEAR PUSH PUSH PUSH PUSH PUSH PUSH PUSH PUSH AX DI DS ES DS ES DS ES JCXZ CP_LP1_END LODSB JE CP_LP1_RPT CMP AL, 9 JNE CP_LP1_END LOOP CP_LP1 JCXZ CP_LP2_END CMP JE CMP JE LOOP AL, ' ' CP_LP2_END AL, 9 CP_LP1_END CP_LP1 CP_LP2: CP_LP1_RPT: CP_LP1_END: CP_LP2: CP_LP2_END: JCXZ CP_LP2_END CMP AL, '' JE CP_LP2_END CMP AL, 9 JMP CP_LP2_END STOSB LODSB LOOP CP_LP2 MOV AL, 0 STOSB JCXZ CP_1 DEC CX CP_1: POP POP POP POP RET ES DS DI AX 457 COPY_PRM ENDP CODE ENDS END MAIN TITLE PROGRAMMING ASSIGNMENT 13-5 PAGE 55, 80 COMMENT | PROGRAM : PA13-5.ASM PROGRAMMER : KADIR GECKIN DATE : 31/12/2000 KULLANICI TANIMLI KAYIT UZUNLUGUYLA BIR DOSYA KOPYALAYAN PROGRAM DOSYA ISIMLERINI DOS'UN KOMUT SATIRINDAN ALIR INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,OPEN_FILE, CREATE_FILE, READ_STREAM, WRITE_STREAM VE CLOSE_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : NONE OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;PSP SEGMENT OUTSIDE PROGRAM (AT COMBINE TYPE) ===================== PSP_SEG SEGMENT AT 0 INT_20_INST MEM_SIZE RSV_1 DOS_CALL_INST TERM_ADD BREAK_ADD ERROR_ADD RSV_2 ENV_SEG_ADD DB DW DB DB DB DD DD DB DW ?, ? ? ? 5 DUP (?) ? ? ? 22 DUP (?) ? RSV_3 FUNCT_DISP PARAM_1 PARAM_2 CMD_LEN CMD_LINE DEF_DTA DB DW DB DB DB DB ORG DB 34 DUP (?) 6 DUP (?) 16 DUP (?) 20 DUP (?) ? 127 DUP (?) 80H 128 DUP (?) PSP_SEG ENDS ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB 64 DUP ('*STACK*') 458 STACK ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF REC_BUF DB DB 4 DUP ('I/O BFR') 32 DUP('RECORD BUFFER***') R_LEN I_HNDL O_HNDL DW DW DW ? ? ? DATA ENDS ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME MAIN PROC CS:CODE, SS:STACK FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, AX AX, DS, DS: MOV SUB MOV MOV CL, CH, SI, DI, 0 DATA AX DATA CMD_LEN CH OFFSET CMD_LINE OFFSET IO_BUF CALL COPY_PRM OPEN_FILE <OFFSET IO_BUF>, R, BX, AL JNC C_1 DSPLY_IMMED_STR <7, 'Bad input file name;'> DSPLY_IMMED_STR 'aborting' JMP EXIT C_1: MOV I_HNDL, BX CALL COPY_PRM CREATE_FILE <OFFSET IO_BUF>, , BX, AL JNC C_2 DSPLY_IMMED_STR <7, 'Bad output file name;'> DSPLY_IMMED_STR 'aborting.' JMP CLS_I C_2: MOV LP_1: O_HNDL, BX DSPLY_IMMED_STR <13, DSPLY_IMMED_STR 'Rec DSPLY_IMMED_STR '( 1 INPUT_STR <OFFSET CNV_UNS_STR <OFFSET JC CMP 10, 10> len to use copy ' - 512 )' IO_BUF>, 3 IO_BUF>, AX C_3 AX, 512 459 JA CMP JA C_3: C_3 AX, 0 LP1_END DSPLY_IMMED_STR <7, 'Invalid lenght; '> DSPLY_IMMED_STR 'try again' JMP LP_1 LP1_END: MOV R_LEN, AX MOV CX, 0 DSPLY_IMMED_STR <'Copy the file', 13, 10> LP_2: JC CMP JE JC CMP CMP JA JMP MOV AX, I_HNDL MOV BX, R_LEN LP2_END BX, 0 LP2_END MOV AX, O_HNDL WRITE_STREAM AX, BX, <OFFSET REC_BFR> LP_2_END INC CX LP2_END INC CX R_LEN, BX LP2_END LP_2 LP2_END: JNC CPY_OK CMP JNE CPY_OK: AX, I_HNDL WRT_ERR DSPLY_IMMED_STR <7, 'Error reading '> DSPLY_IMMED_STR 'output file.' JMP DONE DSPLY_IMMED_STR CNV_UNS_STR DSPLY_STR DSPLY_IMMED_STR <10, 10, 'Copy complete - '> <OFFSET IO_BUF>, CX <OFFSET IO_BUF> <'records copied.', 13 ,10> DONE: CLS_O: MOV AX, O_HNDL CLOSE_FILE AX JNC CLSO_OK DSPLY_IMMED_STR 'Unable to close output file' DSPLY_IMMED_STR <13, 10> CLS_OK: CLS_I: MOV AX, I_HNDL CLOSE_FILE AX JNC CLSO_OK DSPLY_IMMED_STR 'Unable to close input file' DSPLY_IMMED_STR <13, 10> EXIT: MAIN RET ENDP COPY PROC NEAR PUSH AX 460 CP_LP1: PUSH PUSH PUSH PUSH PUSH POP POP DI DS ES DS ES DS ES JCXZ LODSP CMP JE CMP JNE CP_LP1_END CP_LP1_RPT: CP_LP1_END: AL, ' ' CP_LP1_RPT AL, 9 CP_LP1_END LOOP JCXZ CP_LP1 CP_LP2_END CP_LP2: MOV AL, ' ' JE CP_LP2_END CMP AL, 9 JE CP_LP2_END STOSB LODSB LOOP CP_LP2 CP_LP1_END: MOV AL, 0 STOSB JCXZ CP_1 DEC CX CP_1: COPY_PRM CODE POP POP POP POP RET ENDP ENDS END ES DS DI AX MAIN TITLE PROGRAMMING ASSIGNMENT 12-6 PAGE 55, 80 COMMENT | PROGRAM : PA12-6.ASM PROGRAMMER : KADIR GECKIN DATE : 01/01/2001 BIR OKUYUSLA VE BIR YAZISLA DOSYA KOPYALAYAN PROGRAM (DOSYA ASAGI YUKARI 32768 BYTE'TAN BUYUK) DOSYA ISIMLERINI DOSUN KOMUT SATIRINDAN ALIR INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,OPEN_FILE, CREATE_FILE,SEEK, READ_STREAM, WRITE_STREAM VE CLOSE_FILE 461 YAPITASLARI KULLANILIR. INPUT PARAM'S : SOURCE FILE NAME = 1ST PARAMETER IN COMMAMD-LINE TAIL DESTINATION FILE NAME = 2ND PARAMETER IN COMMAMD-LINE TAIL OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;PSP SEGMENT OUTSIDE PROGRAM (AT COMBINE TYPE) ===================== PSP_SEG SEGMENT AT 0 RSV_1 DOS_CALL_INST TERM_ADD BREAK_ADD ERROR_ADD RSV_2 ENV_SEG_ADD DB DB DB DD DD DB DW ? 5 DUP (?) ? ? ? 22 DUP (?) ? RSV_3 FUNCT_DISP PARAM_1 PARAM_2 CMD_LEN CMD_LINE DEF_DTA DB DW DB DB DB DB ORG DB 34 DUP (?) 6 DUP (?) 16 DUP (?) 20 DUP (?) ? 127 DUP (?) 80H 128 DUP (?) PSP_SEG ENDS ;STACK SEGMENT ================================================== STACK SEGMENT PARA STACK 'STACK' DB STACK 64 DUP ('*STACK*') ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF REC_BFR I_HNDL O_HNDL PRM_LEN FILE_SIZE DB DB DW DW DW DW DATA ENDS 4 DUP ('I/O BFR') 32368 DUP('*') ? ? ? ? ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' ASSUME CS:CODE, SS:STACK ES:PSP_SEG 462 MAIN PROC FAR PUSH MOV PUSH MOV MOV ASSUME DS AX, 0 AX AX, DATA DS, AX DS:DATA MOV CL, CMD_LEN SUB CH, CH MOV SI, OFFSET CMD_LINE MOV DI, OFFSET IO_BUF CALL COPY_PRM OPEN_FILE <OFFSET IIO_BUF>, R, AX JNC C_1 DSPLY_IMMED_STR <7, 'Bad input file name;'> DSPLY_IMMED_STR 'aborting.' JMP EXIT C_1: MOV MOV SUB MOV SEEK JNC C_2: C_3: CMP JA CMP JBE I_HNDL, AX PRM_LEN, CX BX, BX CX, BX AX, END, BX, CK C_2 DSPLY_IMMED_STR 'Error seeking end of file' DSPLY_IMMED_STR <13, 10> JMP CLS_1 BX, 0 C_3 CX, 32768 C_4 DSPLY_IMMED_STR 'File too big (GT 32768' DSPLY_IMMED_STR <'bytes)',13, 10> JMP CLS_I C_4: SEEK AX, BEG, BX, BX JNC C_5 DSPLY_IMMED_STR 'Error seeking begining ' DSPLY_IMMED_STR <' of file',13, 10> JMP CLS_I C_5: MOV FILE_SIZE, CX MOV CX, PRM_LEN CALL COPY_PRM CREATE_FILE <OFFSET IO_BUF>, , AX JNC C_6 DSPLY_IMMED_STR <7, 'Bad output filename;'> DSPLY_IMMED_STR 'aborting' JMP CLS_I C_6: MOV O_HNDL, AX MOV CX, FILE_SIZE DSPLY_IMMED_STR <'Copying the file',13, 10> MOV AX, I_HNDL READ_STREAM AX, CX JNC C_7 DSPLY_IMMED_STR 'Error reading input ' 463 DSPLY_IMMED_STR <'file',13, 10> JMP DONE C_7: MOV AX, O_HNDL WRITE_STREAM AX, CX, <OFFSET REC_BFR> JNC C_8 DSPLY_IMMED_STR 'Error writitng to output ' DSPLY_IMMED_STR <'file',13, 10> JMP DONE C_8: DSPLY_IMMED_STR <10,10,'Copy complete - '> CNV_UNS_STR <OFFSET IO_BUF>, CX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <' bytes copied.',13, 10> DONE: CLS_O: C_9: CLS_I: MOV AX, O_HNDL CLOSE_FILE AX JNC C_9 DSPLY_IMMED_STR 'Unable to close output ' DSPLY_IMMED_STR <'file',13, 10> MOV AX, I_HNDL CLOSE_FILE AX JNC C_10 DSPLY_IMMED_STR 'Unable to close input ' DSPLY_IMMED_STR <'file',13, 10> C_10: EXIT: MAIN RET ENDP ;COPY PRM --------------------------------------------------------------COPY_PRM PROC NEAR PUSH PUSH PUSH PUSH PUSH PUSH POP POP AX DI DS ES DS ES DS ES JCXZ CP_LP1_END LODSB CMP AL, ' ' JE CP_LP1_PPT CMP AL, 9 JNE CP_LP1_END CP_LP1_RPT: LOOP CP_LP1 CP_LP1_END: JCXZ CP_LP2_END CP_LP1: CP_LP2: JCXZ CP_LP2_END CMP AL, ' ' JE CP_LP2_END CMP AL, 9 JE CP_LP2_END STOSB LODSB LOOP CP_LP2 CP_LP2_END: 464 MOV STOSB JCXZ DEC AL, 0 CP_1 CX CP_1: POP POP POP POP RET ENDP ENDS END COPY_PRM CODE ES DS DI AX MAIN TITLE PROGRAMMING ASSIGNMENT 13-7 PAGE 55, 80 COMMENT | PROGRAM : PA13-7.ASM PROGRAMMER : KADIR GECKIN DATE : 01/01/2000 BIR DOSYANIN ISMINI DEGISTIREN COM PORGRAM ******* MUST USE EXE2BIN TO CONVERT TO A COM FILE ******* INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR VE REN_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : OLD FILE NAME = 1ST PARAMETER IN COMMAMD-LINE TAIL NEW FILE NAME = 2ND PARAMETER IN COMMAMD-LINE TAIL OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;PSP SEGMENT OUTSIDE PROGRAM (AT COMBINE TYPE) ===================== PSP_SEG SEGMENT AT 0 INT_20_INST MEM_SIZE RSV_1 DOS_CALL_INST TERM_ADD BREAK_ADD ERROR_ADD RSV_2 ENV_SEG_ADD DB DW DB DB DB DD DD DB DW ?, ? ? ? 5 DUP (?) ? ? ? 22 DUP (?) ? RSV_3 FUNCT_DISP PARAM_1 DB DW DB 34 DUP (?) 6 DUP (?) 16 DUP (?) 465 PARAM_2 CMD_LEN CMD_LINE DEF_DTA DB DB DB ORG DB PSP_SEG ENDS 20 DUP (?) ? 127 DUP (?) 80H 128 DUP (?) ;DATA SEGMENT =================================================== DATA ENTRY: SEGMENT PARA PUBLIC 'DATA' ORG 100H JMP NEAR PTR MAIN IO_BUF1 IO_BUF2 DB DB 31 DUP('*') 31 DUP('*') DATA ENDS ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' MAIN PROC MOV SUB MOV MOV CALL MOV CALL FAR CL, CMD_LEN CH, CH SI, OFFSET CMD_LINE DI, OFFSET IO_BUF1 COPY_PRM DI, OFFSET IO_BUF2 COPY_PRM REN_FILE <OFFSET IO_BUF1>,<OFFSET IO_BUF2>, AL JC M_ERR DSPLY_IMMED_STR <'File renamed', 13, 10> JMP DONE M_ERR: DSPLY_CHR 7 CMP AL, 02H JNE C2_LBL DSPLY_IMMED_STR <'File not found', 13, 10> JMP C_END C2_LBL: CMP JNE AL, 03H C3_LBL DSPLY_IMMED_STR <'Path not found', 13, 10> JMP C_END C3_LBL CMP JNE AL, 05H C4_LBL DSPLY_IMMED_STR <'Access denied (file', 13, 10> JMP SHORT C_END DSPLY_IMMED_STR <'already exist', 13, 10> JMP SHORT C_END C4_LBL CMP JNE AL, 11H C5_LBL DSPLY_IMMED_STR <'Not same dev,ce', 13, 10> JMP SHORT C_END 466 C5_LBL: DSPLY_IMMED_STR <10, 'Error: '> SUB AH, AH CNV_UNS_STR <OFFSET IO_BUF1>, AX, 16 DSPLY_STR <OFFSET IO_BUF1> DSPLY_IMMED_STR <'H',13, 10> C_END: DONE: INT MAIN 20 ENDP ;COPY_PRM ---------------------------------------------------------------COPY_PRM PROC NEAR PUSH PUSH AX DI JCXZ CP_LP1_END LODSB CP_LP1: CP_LP1_RPT: CP_LP1_END: CMP AL, '' JE CP_LP1_RPT CMP AL, 9 JNE CP_LP1_END LOOP CP_LP1 JCXZ CP_LP2_END CMP JE CMP JE STOSB LODSB LOOP AL, ' ' CP_LP2_END AL, 9 CP_LP1_END CP_LP2: LP2_END: CP_LP2_END: CP_LP2 MOV AL, 0 STOSB JCXZ CP_1 DEC CX CP_1: POP POP RET DI AX COPY_PRM ENDP CODE ENDS END ENTRY TITLE PROGRAMMING ASSIGNMENT 13-8 467 PAGE COMMENT | 55, 80 PROGRAM : PA13-8.ASM PROGRAMMER : KADIR GECKIN DATE : 01/01/2000 KULLANICI TANIMLI KAYIT UZUNLUGUYLA BIR DOSYA KOPYALAYAN COM PROGRAM DOSYA ISIMLERINI DOS'UN KOMUT SATIRINDAN ALIR ******* MUST USE EXE2BIN TO CONVERT TO A COM FILE ******* INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,OPEN_FILE, CREATE_FILE, READ_STREAM, WRITE_STREAM VE CLOSE_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : SOURCE FILE NAME = 1ST PARAMETER IN COMMAMD-LINE TAIL DESTINATION FILE NAME = 2ND PARAMETER IN COMMAMD-LINE TAIL OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;PSP SEGMENT OUTSIDE PROGRAM (AT COMBINE TYPE) ===================== PSP_SEG SEGMENT AT 0 INT_20_INST MEM_SIZE RSV_1 DOS_CALL_INST TERM_ADD BREAK_ADD ERROR_ADD RSV_2 ENV_SEG_ADD DB DW DB DB DB DD DD DB DW ?, ? ? ? 5 DUP (?) ? ? ? 22 DUP (?) ? RSV_3 FUNCT_DISP PARAM_1 PARAM_2 CMD_LEN CMD_LINE DEF_DTA DB DW DB DB DB DB ORG DB 34 DUP (?) 6 DUP (?) 16 DUP (?) 20 DUP (?) ? 127 DUP (?) 80H 128 DUP (?) PSP_SEG ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF REC_BUF DB DB 4 DUP ('I/O BFR') 32 DUP('RECORD BUFFER***') R_LEN DW ? 468 I_HNDL O_HNDL DW DW ? ? DATA ENDS ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' MAIN PROC MOV SUB MOV MOV FAR CL, CH, SI, DI, CMD_LEN CH OFFSET CMD_LINE OFFSET IO_BUF CALL COPY_PRM OPEN_FILE <OFFSET IO_BUF>, R, BX, AL JNC C_1 DSPLY_IMMED_STR <7, 'Bad input file name;'> DSPLY_IMMED_STR 'aborting' JMP EXIT C_1: MOV I_HNDL, BX CALL COPY_PRM CREATE_FILE <OFFSET IO_BUF>, , BX, AL JNC C_2 DSPLY_IMMED_STR <7, 'Bad output file name;'> DSPLY_IMMED_STR 'aborting.' JMP CLS_I C_2: MOV LP_1: DSPLY_IMMED_STR <13, DSPLY_IMMED_STR 'Rec DSPLY_IMMED_STR '( 1 INPUT_STR <OFFSET CNV_UNS_STR <OFFSET JC CMP JA CMP JA C_3: O_HNDL, BX 10, 10> len to use copy ' - 512 )' IO_BUF>, 3 IO_BUF>, AX C_3 AX, 512 C_3 AX, 0 LP1_END DSPLY_IMMED_STR <7, 'Invalid lenght; '> DSPLY_IMMED_STR 'try again' JMP LP_1 LP1_END: MOV R_LEN, AX MOV CX, 0 DSPLY_IMMED_STR <'Copy the file', 13, 10> LP_2: MOV AX, I_HNDL MOV BX, R_LEN JC LP2_END CMP BX, 0 JE LP2_END MOV AX, O_HNDL WRITE_STREAM AX, BX, <OFFSET REC_BFR> JC LP_2_END INC CX 469 CMP CMP JA JMP LP2_END INC CX R_LEN, BX LP2_END LP_2 LP2_END: JNC CPY_OK CMP JNE AX, I_HNDL WRT_ERR DSPLY_IMMED_STR <7, 'Error reading '> DSPLY_IMMED_STR 'output file.' JMP DONE WRT_ERR: DSPLY_IMMED_STR <7, 'Error writing to '> DSPLY_IMMED_STR 'output file.' JMP DONE CPY_OK: DSPLY_IMMED_STR CNV_UNS_STR DSPLY_STR DSPLY_IMMED_STR <10, 10, 'Copy complete - '> <OFFSET IO_BUF>, CX <OFFSET IO_BUF> <'records copied.', 13 ,10> DONE: CLS_O: MOV AX, O_HNDL CLOSE_FILE AX JNC CLSO_OK DSPLY_IMMED_STR 'Unable to close output file' DSPLY_IMMED_STR <13, 10> CLSO_OK: CLS_I: MOV AX, I_HNDL CLOSE_FILE AX JNC CLSO_OK DSPLY_IMMED_STR 'Unable to close input file' DSPLY_IMMED_STR <13, 10> CLSO_OK: EXIT: MAIN INT 20H ENDP ;COPY PRM ---------------------------------------------------------COPY PROC NEAR CP_LP1: CP_LP1_RPT: CP_LP1_END: PUSH PUSH AX DI JCXZ LODSP CMP JE CMP JNE CP_LP1_END AL, ' ' CP_LP1_RPT AL, 9 CP_LP1_END LOOP CP_LP1 470 JCXZ CP_LP2_END CP_LP2: MOV AL, ' ' JE CP_LP2_END CMP AL, 9 JE CP_LP2_END STOSB LODSB LOOP CP_LP2 CP_LP1_END: MOV AL, 0 STOSB JCXZ CP_1 DEC CX CP_1: COPY_PRM CODE COMMENT | POP DI POP AX RET ENDP ENDS END ENTRY TITLE PROGRAMMING ASSIGNMENT 13-9 PAGE 55, 80 PROGRAM : PA13-9.ASM PROGRAMMER : KADIR GECKIN DATE : 01/01/2001 BIR OKUYUSLA VE BIR YAZISLA DOSYA KOPYALAYAN COM PROGRAM (DOSYA ASAGI YUKARI 32768 BYTE'TAN BUYUK) DOSYA ISIMLERINI DOSUN KOMUT SATIRINDAN ALIR ******* MUST USE EXE2BIN TO CONVERT TO A COM FILE ******* INPUT_STR, DSPLY_STR, DSPLY_IMMED_STR ,OPEN_FILE, CREATE_FILE,SEEK, READ_STREAM, WRITE_STREAM VE CLOSE_FILE YAPITASLARI KULLANILIR. INPUT PARAM'S : SOURCE FILE NAME = 1ST PARAMETER IN COMMAMD-LINE TAIL DESTINATION FILE NAME = 2ND PARAMETER IN COMMAMD-LINE TAIL OUTPUT PARAM'S : NONE RETURNS TO DOS, UPON COMPLETION | IF1 INCLUDE CONSOLE.MLB INCLUDE DISK.MLB ENDIF ;PSP SEGMENT OUTSIDE PROGRAM (AT COMBINE TYPE) ===================== PSP_SEG SEGMENT RSV_1 DOS_CALL_INST TERM_ADD DB DB DB ? 5 ? AT 0 DUP (?) 471 BREAK_ADD ERROR_ADD RSV_2 ENV_SEG_ADD DD DD DB DW ? ? 22 DUP (?) ? RSV_3 FUNCT_DISP PARAM_1 PARAM_2 CMD_LEN CMD_LINE DEF_DTA DB DW DB DB DB DB ORG DB 34 DUP (?) 6 DUP (?) 16 DUP (?) 20 DUP (?) ? 127 DUP (?) 80H 128 DUP (?) PSP_SEG ENDS ;DATA SEGMENT =================================================== DATA SEGMENT PARA PUBLIC 'DATA' IO_BUF REC_BFR I_HNDL O_HNDL PRM_LEN FILE_SIZE DB DB DW DW DW DW DATA ENDS 4 DUP ('I/O BFR') 32368 DUP('*') ? ? ? ? ;CODE SEGMENT =================================================== CODE SEGMENT PARA PUBLIC 'CODE' MAIN PROC FAR MOV CL, CMD_LEN SUB CH, CH MOV SI, OFFSET CMD_LINE MOV DI, OFFSET IO_BUF CALL COPY_PRM OPEN_FILE <OFFSET IIO_BUF>, R, AX JNC C_1 DSPLY_IMMED_STR <7, 'Bad input file name;'> DSPLY_IMMED_STR 'aborting.' JMP EXIT C_1: MOV MOV SUB MOV SEEK JNC C_2: C_3: CMP JA CMP JBE I_HNDL, AX PRM_LEN, CX BX, BX CX, BX AX, END, BX, CK C_2 DSPLY_IMMED_STR 'Error seeking end of file' DSPLY_IMMED_STR <13, 10> JMP CLS_I BX, 0 C_3 CX, 32768 C_4 DSPLY_IMMED_STR 'File too big (GT 32768' 472 DSPLY_IMMED_STR <'bytes)',13, 10> JMP CLS_I C_4: SEEK AX, BEG, BX, BX JNC C_5 DSPLY_IMMED_STR 'Error seeking begining ' DSPLY_IMMED_STR <' of file',13, 10> JMP CLS_I C_5: MOV FILE_SIZE, CX MOV CX, PRM_LEN CALL COPY_PRM CREATE_FILE <OFFSET IO_BUF>, , AX JNC C_6 DSPLY_IMMED_STR <7, 'Bad output filename;'> DSPLY_IMMED_STR 'aborting' JMP CLS_I C_6: MOV O_HNDL, AX MOV CX, FILE_SIZE DSPLY_IMMED_STR <'Copying the file',13, 10> MOV AX, I_HNDL READ_STREAM AX, CX JNC C_7 DSPLY_IMMED_STR 'Error reading input ' DSPLY_IMMED_STR <'file',13, 10> JMP DONE C_7: MOV AX, O_HNDL WRITE_STREAM AX, CX, <OFFSET REC_BFR> JNC C_8 DSPLY_IMMED_STR 'Error writitng to output ' DSPLY_IMMED_STR <'file',13, 10> JMP DONE C_8: DSPLY_IMMED_STR <10,10,'Copy complete - '> CNV_UNS_STR <OFFSET IO_BUF>, CX DSPLY_STR <OFFSET IO_BUF> DSPLY_IMMED_STR <' bytes copied.',13, 10> DONE: CLS_O: C_9: CLS_I: MOV AX, O_HNDL CLOSE_FILE AX JNC C_9 DSPLY_IMMED_STR 'Unable to close output ' DSPLY_IMMED_STR <'file',13, 10> MOV AX, I_HNDL CLOSE_FILE AX JNC C_10 DSPLY_IMMED_STR 'Unable to close input ' DSPLY_IMMED_STR <'file',13, 10> C_10: EXIT: MAIN RET ENDP ;COPY PRM --------------------------------------------------------------COPY_PRM PROC NEAR PUSH PUSH AX DI 473 JCXZ CP_LP1_END LODSB CMP AL, ' ' JE CP_LP1_PPT CMP AL, 9 JNE CP_LP1_END CP_LP1_RPT: LOOP CP_LP1 CP_LP1_END: JCXZ CP_LP2_END CP_LP1: CP_LP2: JCXZ CP_LP2_END CMP AL, ' ' JE CP_LP2_END CMP AL, 9 JE CP_LP2_END STOSB LODSB LOOP CP_LP2 CP_LP2_END: MOV STOSB JCXZ DEC AL, 0 CP_1 CX CP_1: COPY_PRM CODE POP ES POP DS RET ENDP ENDS END ENTRY 474 ASSEMBLY PROGRAM ÖRNEKLERİ BÖLÜM-9: COMMENT | PA14-1.ASM KULLANIICI TARAFINDAN BEL˜R˜LENEN SURE VE FRAKANSTA SPEAKER CIKTISI URETIR !!! MUST BE CONVERTED TO A .COM FILE !!! | PAGE TITLE 55, 80 PA14-1.ASM INCLUDE P_GROUP CONSOLE.MLB GROUP DATA, CODE ASSUME CS:P_GROUP, DS:P_GROUP, ES:P_GROUP ;DATA SEGMENT ============================================================ DATA SEGMENT PARA PUBLIC 'DATA' ENTRY: ORG JMP 100H NEAR PTR MAIN SOUND_ON DURATION FREQ I1CH_VCTR DB DB DB DB DB DB DB DB DW DW DD 6 DUP('#') 'Enter desired frequency ' '(19 - 65535, or 0 to quit) ',0 10, 10, 'Invalid input - ' 'Press any key to try again ',0 'Enter desired duration in miliseconds ' '(55 - 65535)' 0 0 0 ? DATA ENDS IO_BUF F_MSG INV_MSG D_MSG ;CODE SEGMENT ======================================================== MAIN GET_F: PROC FAR PUSH MOV MOV INT MOV MOV POP MOV MOV MOV INT ES AH, 35H AH, 1CH 21H WORD PTR I1CH_VCTR, BX WORD PTR I1CH_VCTR + 2, ES ES DX, OFFSET P_GROUP AH, 25H AH, 1CH 21H CLS LOCATE 4, 0 475 M_1: INC_F: M_2: DSPLY_STR INPUT_STR CNV_STR_UNS JC INV_F CMP BX, 0 JNE M_1 JMP M_RET CMP BX, 19 JAE M_2 DSPLY_STR INPUT_CHR JMP GET_F <OFFSET INV_MSG> AL MOV FREQ, BX CLS 7, 0 LOCATE 7, 0 DSPLY_STR <OFFSET INV_MSG> INPUT_STR CNV_STR_UNS JC CMP JAE INV_D: <OFFSET F_MSG> <OFFSET IO_BUF>, 5 <OFFSET IO_BUF>, BX <OFFSET IO_BUF>, 5 <OFFSET IO_BUF>, BX INV_D BX, 55 M_2A DSPLY_STR INPUT JMP MOV <OFFSET INV_MSG> AL GET_D DURATION, BX MOV MOV DIV MOV MOV DX, 12H AX, 34DCH FREQ BX, AX AL, 0B6H OUT MOV OUT MOV OUT 43H, AL AL, BL 42H, AL AL, BH 42H, AL IN OR AL, 61H AL, 03H OUT MOV JMP 61H, AL SOUND_ON, OFFH GET_F M_RET: IF_1: CMP JE SOUND_ON, 0 END_IF1 DSPLY_IMMED_STR <'Turning speaker off.',13, 10> IN AL, 61H AND AL, 0FDH OUT 61H, AL END_IF1: PUSH MOV MOV DS DX, WORD PTR ES:I1CH_VCTR DX, WORD PTR ES:I1CH_VCTR + 2 476 MOV AH, 25H MOV AL, 1CH INT 21H POP DS DSPLY_IMMED_STR <10, 10, 'Good-bye', 13, 10, 10> INT 20H MAIN ENDP BTICK_SVC PROC NEAR PUSH PUSH POP ASSUME DS CS DS DS:P_GROUP IF_2: CMP JE SOUND_ON, 0 END_IF2 SUB DURATION, 55 IF_3: JA END_IF3 IN AL, 61H AND AL, 0FDH OUT AND 61H, AL AL, OFDH OUT MOV 61H, AL SOUND_ON, 0 END_IF3: END_IF2: POP ASSUME IRET BTICK_SVC CODE COMMENT ENDP ENDS END DS DS:NOTHING ENTRY | PA14-2.ASM SAATI DURDURAN PROGRAM !!! MUST BE CONVERTED TO COM FILE USING EXE2BIN !!! ICLUDES TWO INTERRUPT SERVICES ROUTINES: 08H - 8253 TIMER TICK (IRQ0) 09H - KEYBOARD (IRQ1) | PAGE 55, 80 TITLE PA14-2.ASM INCLUDE P_GROUP CONSOLE.MLB GROUP DATA, CODE 477 ASSUME CS:P_GROUP, DS:P_GROUP, ES:P_GROUP ;DATA SEGMENT ============================================================ DATA SEGMENT PARA PUBLIC 'DATA' ENTRY: ORG JMP 100H NEAR PTR MAIN BLANKS ESC_FLG CLCK_SWTCH O_BUF 09H_VCTR 08H_VCTR OURS MINUTES SECONDS SECS TCKS DB DB DB DB DB DB DB DB DB DB DB DD DD DB DB DB DW DB ' S T O P W A ' Press <space 13, 10, 10 ' Press <space 13, 10, 10 'Press <Esc> o 0 ' ' 0 0 7 DUP('#') ? ? 0 0 0 0 11 DATA ENDS INIT_MSG T C H', 13 ,10 ,10, 10 bar> to start clock' bar> again to stop clock' quit' ;CODE SEGMENT ======================================================== CODE SEGMENT MAIN PROC PARA PUBLIC 'CODE' FAR CLS LOCATE 4, 25 DSPLY_STR <OFFSET INIT_MSG> LOCATE 18, 28 DSPLY_IMMED_STR 'Hours:' LOCATE 20, 26 DSPLY_IMMED_STR 'Minutes:' LOCATE 20, 26 DSPLY_IMMED_STR 'Seconds:' LOCATE 20, 21 DSPLY_IMMED_STR 'Miliseconds:' PUSH MOV MOV INT MOV MOV MOV MOV INT MOV MOV ES AH, 35H AL, 08H 21H WORD PTR WORD PTR AH, 35H AL, 09H 21H WORD PTR WORD PTR MOV DX, OFFSET P_GROUP:TIMER_SVC MOV AH, 25H IO8H_VCTR, BX IO8H_VCTR + 2, ES IO9H_VCTR, BX IO9H_VCTR+ 2, ES 478 MOV INT MOV MOV MOV INT MOV MOV MOV INT MOV AL, 21H DX, AH, AH, 21H DX, AH, AL, 21H AL, 08H OUT MOV OUT MOV OUT 43H, AL AL, 4EH 40H, AL AL, 17H 40H, AL OFFSET P_GROUP:KBRD_SVC 25H 08H OFFSET P_GROUP:KBRD_SVC 25H 08H 036H P_BEG: LOCATE 18, 35 MOV AL, HOURS SUB AH, AH CNV_UNS_STR <OFFSET IO_BUF>, AX DSPLY_STR <OFFSET IO_BUF> DSPLY_STR <OFFSET BLANKS> LOCATE MOV CNV DSPLY_STR DSPLY_STR 19, 35 AL ,MINUTES <OFFSET IO_BUF>, AX <OFFSET IO_BUF> <OFFSET BLANK> LOCATE MOV CNV DSPLY_STR DSPLY_STR 20, 35 AL ,SECONDS <OFFSET IO_BUF>, AX <OFFSET IO_BUF> <OFFSET BLANK> LOCATE MOV CNV DSPLY_STR DSPLY_STR 21, 35 AX ,MSECS <OFFSET IO_BUF>, AX <OFFSET IO_BUF> <OFFSET BLANK> CMP JNE JMP LP_END: MOV ESC_FLG, 0 LP_END LP_BEG AL, 036H OUT MOV OUT OUT 43H, AL AL, 0 40H, AL 40H, AL PUSH MOV MOV DS DX, WORD PTR ES: I08H_VCTR DX, WORD PTR ES: I08H_VCTR + 2 MOV MOV INT AH, 25H AL, 08H 21H 479 MOV MOV DX, WORD PTR ES: I09H_VCTR DX, WORD PTR ES: I09H_VCTR + 2 MOV MOV INT POP AH, 25H AL, 09H 21H DS LOCATE INT MAIN 25, 0 2OH ENDP ASSUME DS:NOTHING, ES:NOTHING ;8253 TIMER, CHANNEL 2 SERVICE -----------------------------------------TIME_SVC PROC PUSHF PUSH PUSH POP ASSUME CMP JE NEAR DS CS DS DS:P_GROUP CLCK_SWTCH, 0 END_IF1 ADD MSECS, 5 CMP MSECS, 1000 JB END_IF2 SUB MSEC, 1000 INC SECONDS CMP JB SECONDS, 60 END_IF3 SUB SECONDS, 60 INC MINUTES CMP JB MINUTES, 60 END_IF4 SUB INC MINUTES, 60 HOURS END_IF4: END_IF3: END_IF2: END_IF1: DEC IF_5: TICKS JNZ MOV ELSE_5: ELSE_5 TICKS, 11 POP POPF ASSUME JMP DS PUSH NOV OUT POP POP AX AL, 20H 20H, AL AX DS DS:NOTHING IO8H_VCTR 480 POPF ASSUME IRET DS:NOTHING END_IF5: TIMER_SVC ENDP ;KEYBOARD SERVICE ------------------------------------------------------KBRD_SVC IF_6: C_1: C_2: C_3: PROC NEAR PUSH PUSH PUSH PUSH ASSUME AX DS CS DS DS:P_GROUP IN MOV IN OR OUT AND OUT AL, 60H AH, AL AL, 61H AL, 80H 61H, AL AL, 7FH 61H, AL TEST JNZ AH, 80H END_IF6 CMP JNE NOT JMP CMP JNE AH, 39H C_2 CLCK_SWTCH C_END AH, 1CH C_3 SUB AX, AX MOV MSECS, AX MOV SECONDS, AL MOV MINUTES, AL MOV HOURS, AL JMP C_END CMP JNE AH, 01H C_END MOV CLCK_SWTCH, 0 NOT ESC_FLG C_END: END_IF6: MOV OUT POP POP ASSUME IRET KBRD_SVC CODE AL, 20H 20H, AL DS AX DS:NOTHING ENDP ENDS END ENTRY 481 COMMENT | PA14-3.ASM PIANO PROGRAMI !!! MUST BE CONVERTED TO COM FILE USING EXE2BIN !!! ICLUDES TWO INTERRUPT SERVICES ROUTINE: 09H - KEYBOARD (IRQ1) | PAGE 55, 80 TITLE PA14-3.ASM INCLUDE P_GROUP CONSOLE.MLB GROUP DATA, CODE ASSUME CS:P_GROUP, DS:P_GROUP, ES:P_GROUP ;DATA SEGMENT ============================================================ DATA SEGMENT PARA PUBLIC 'DATA' ENTRY: ORG JMP 100H NEAR PTR MAIN DB DB DB DB DB DB DB DB DB DB DB DB DB DD DW ENDS ' P I A N O ', 13 ,10 ,10, 10 ' Turns lower 2 rows of keyboard into ' 'piano keys',13, 10 'Key_note correspondence is as follows:' 13, 10, 10 ' Keys:', 13, 10 ' S D G H J', 13, 10 ' Z X C V B N M ,' 13, 10, 'Notes:', 13, 10 ' C# D# F# G# A#', 13, 10 ' C D E F G A B C' 13, 10, 10, 10, 'Press <Esc> to quit', 0 0 ? 0 INIT_MSG ESC_FLG 09H_VCTR KEYS DATA ;CODE SEGMENT ======================================================== CODE SEGMENT MAIN PROC PARA PUBLIC 'CODE' FAR CLS LOCATE 4, 25 DSPLY_STR <OFFSET INIT_MSG> PUSH ES MOV AH, 35H MOV AL, 09H INT 21H MOV WORD PTR I09H_VCTR, BX MOV WORD PTR I09H_VCTR + 2, ES POP ES 482 MOV DX, P_GROUP:KBRD_SVC MOV MOV INT AH, 25H AL, 09H 21H LP_BEG: CMP JE PUSH MOV MOV ESC_FLG, 0 LP_BEG DS DX, WORD PTR ES:IO9H_VCTR DS, WORD PTR ES:IO9H_VCTR + 2 MOV AH, 25H MOV AL, 09H INT 21H INT DS IN AL, 61H AND AL, 0FDH OUT 61H, AL LOCATE 25, 0 INT 20H MAIN ENDP ASSUME DS:NOTHING, ES:NOTHING ; KEYBOARD SERVICE -----------------------------------------------------KBRD_SVC PROC NEAR PUSH AX PUSH CX PUSH DX PUSH DS PUSH CS POP DS ASSUME DS:P_GROUP IN MOV IN OR OUT AND OUT MOV AND C_1: C_2: CMP JNE AL, 60H AH, AL AL, 61H AL, 80H 61H, AL AL, 7FH 61H, AL AL, AH AL, 7FH AL, 44 C_2 MOV DX, 1 MOV CX, 9108 JMP C_END CMP JNE AL, 31 C_3 MOV DX, 2 MOV CX, 8597 JMP C_END 483 C_3: CMP JNE AL, 45 C_4 MOV DX, 4 MOV CX, 8115 JMP C_END C_4: CMP JNE AL, 32 C_5 MOV DX, 8 MOV CX, 7659 JMP SHORT C_END C_5: CMP JNE AL, 46 C_6 MOV DX, 16 MOV CX, 7229 JMP SHORT C_END C_6: CMP JNE AL, 47 C_7 MOV DX, 32 MOV CX, 6823 JMP SHORT C_END C_7: CMP JNE AL, 34 C_8 MOV DX, 64 MOV CX, 6441 JMP SHORT C_END C_8: CMP JNE AL, 48 C_9 MOV DX, 128 MOV CX, 6079 JMP SHORT C_END C_9: CMP JNE AL, 35 C_10 MOV DX, 256 MOV CX, 5738 JMP SHORT C_END C_10: CMP JNE AL, 49 C_11 MOV DX, 512 MOV CX, 5416 JMP SHORT C_END C_11 CMP JNE AL, 36 C_12 MOV DX, 1024 MOV CX, 5112 JMP SHORT C_END C_12: CMP JNE AL, 50 C_7 MOV DX, 2048 MOV CX, 4825 JMP SHORT C_END C_13: CMP JNE AL, 51 C_7 484 MOV MOV JMP C_14: CMP JNE C_ELSE: C_END: AL, 1 C_ELSE MOV ESC_FLG, OFFH JMP SHORT KBS_RET JMP SHORT KBS_RET JMP IF_1: DX, 4096 CX, 4554 SHORT C_END SHORT KBS_RET TEST AH, 80H JNZ ELSE_1 MOV AL, 0B6H OUT MOV OUT MOV OUT 43H, AL AL, CL 42H, AL AL, CH 42H, AL IF_2: CMP JNE KEYS, 0 END_IF2 IN AL, 61H OR AL, 03H OUT 61H, AL END_IF2: OR JMP NOT AND JNZ KEYS, DX END_IF1 DX KEYS, DX END_IF3 IN AL, 61H AND AL, 0FDH OUT 61H, AL ELSE_1: IF_3: END_IF3: END_IF1: KBS_RET: MOV AL, 20H OUT 20H, AL POP DS POP DX POP CX POP AX ASSUME DS:NOTHING IRET KBRD_SVC CODE COMMENT ENDP ENDS END | ENTRY PA14-4.ASM 485 STANDART KLAVYE UZERINDE (83 - TUSLU) <PRTSC> TUSUNU ETKISISLESTIRIR GELISMIS (101- TUSLU) KLAVYE ILE CALISMAZ PROGRAM MUST BE CONVERTED TO A .COM FILE WITH EXE2BIN | PAGE 55, 80 TITLE PA14-4.ASM INCLUDE CONSOLE.MLB P_GROUP GROUP ASSUME RE_DATA, RES_CODE, DATA, CODE CS:P_GROUP ;RESIDENT DATA SEGMENT ================================================ RES_DATA SEGMENT PARA PUBLIC 'RES_DATA' ENTRY: ORG JMP 100H NEAR PTR INSTALL I09H_VCTR RES_LBL RES_DATA DD DB ENDS 0 '*PA14-4' ;RESIDENT CODE SEGMENT ================================================== RES_CODE SEGMENT BYTE PUBLIC 'RES_CODE' KBD_SVC PROC NEAR PUSH PUSH PUSH PUSH POP ASSUME IN AND IF_1: CMP JNE IN OR OUT AND OUT MOV OUT POP POP POPF IRET ELSE_1: END_IF1: KBD_SVC RES_CODE AX DS CS DS DS:P_GROUP AL, 60H AL, 7FH AL, 37H ELSE_1 AL, 61H AL, 80H 61H, AL AL, 7FH 61H, AL AL, 20H 20H, AL DS AX POP DS POP AX POPF ASSUME DS:NOTHING JMP I09H_VCTR ENDP ENDS 486 ;NON-RESIDENT CODE SEGMENT ============================================== DATA SEGMENT PARA PUBLIC 'CODE' ASSUME INSTALL PROC CS:P_GROUP, DS:P_GROUP FAR CLS DSPLY_STR MOV MOV INT MOV SUB MOV AH, AH, 21H DI, DI, SI, MOV CLD REP CX, 8 JNE ELSE3: <OFFSET P_GROUP:INS_MSG> 35H 09H BX 8 OFFSET RES_LBL CMPSB ELSE3 INT 20H MOV MOV MOV MOV MOV INT MOV INT WORD PTR I09H_VCTR, BX WORD PTR I09H_VCTR +2, ES DX, OFFSET P_GROUP:KBD_SVC AH, 25H AH, 09H 21H DX, OFFSET P_GROUP:INS_MSG 27H END_IF3: INSTALL CODE COMMENT ENDP ENDS END ENTRY | PA14-5.ASM <NUMLOCK> TUSUNU ETKISIZLESTIREN PROGRAM PROGRAM MUST BE CONVERTED TO A .COM FILE WITH EXE2BIN | PAGE 55, 80 TITLE PA14-5.ASM INCLUDE CONSOLE.MLB P_GROUP GROUP ASSUME RE_DATA, RES_CODE, DATA, CODE CS:P_GROUP ;RESIDENT DATA SEGMENT ================================================ RES_DATA SEGMENT PARA PUBLIC 'RES_DATA' 487 ENTRY: ORG JMP 100H NEAR PTR INSTALL I09H_VCTR RES_LBL RES_DATA DD DB ENDS 0 '*PA14-5' ;RESIDENT CODE SEGMENT ================================================== RES_CODE SEGMENT BYTE PUBLIC 'RES_CODE' KBD_SVC PROC NEAR PUSH PUSH PUSH PUSH POP ASSUME IN AND IF_1: CMP JNE IN OR OUT AND OUT MOV OUT POP POP POPF IRET ELSE_1: END_IF1: KBD_SVC RES_CODE AX DS CS DS DS:P_GROUP AL, 60H AL, 7FH AL, 45H ELSE_1 AL, 02H AL, 80H 61H, AL AL, 7FH 61H, AL AL, 20H 20H, AL DS AX POP DS POP AX POPF ASSUME DS:NOTHING JMP I09H_VCTR ENDP ENDS ;NON - RESIDENT DATA SEGMENT ========================================== CODE SEGMENT PARA PUBLIC 'DATA' INS_MSG DB DB DB DB DB DATA ENDS 7, '<<<<<<<<<<<<<<< PA14-5 is now' 'installed.>>>>>>>>>>>>', 13,10,10,10 'The <Numlock> key is disabled. ' ' To Cancel PA14-5', reboot the system.' 13, 10, 0 ;NON-RESIDENT CODE SEGMENT ============================================== DATA SEGMENT PARA PUBLIC 'CODE' ASSUME CS:P_GROUP, DS:P_GROUP 488 INSTALL PROC FAR CLS DSPLY_STR MOV MOV INT MOV SUB MOV AH, AH, 21H DI, DI, SI, MOV CLD REP CX, 8 JNE ELSE3: <OFFSET P_GROUP:INS_MSG> 35H 09H BX 8 OFFSET RES_LBL CMPSB ELSE3 INT 20H MOV MOV MOV MOV MOV INT MOV INT WORD PTR I09H_VCTR, BX WORD PTR I09H_VCTR +2, ES DX, OFFSET P_GROUP:KBD_SVC AH, 25H AH, 09H 21H DX, OFFSET P_GROUP:INS_MSG 27H END_IF3: INSTALL CODE ENDP ENDS END ENTRY 489 490