💻 Bilgisayar, 💾 Programlama

Mikro İşlemciler Projesi

Ege Üniversitesi Bilgisayar Mühendisliği 3. Sınıflar için 4 Ocak 2010 Pazartesi gününe verilen mikro ödevi için benim çözümlerimi yazıda bulabilirsiniz.

Projeyi yapmanın zor geldiğini söylemeliyim en başta. Oturup C yazar gibi ASM yazmak olacak iş değilmiş onu fark ettim. Baktım, adım atamıyorum, proje bana bakıyor, ben projeye, dedim bu iş böyle olmayacak.

Açtım boş bir sayfa, C’ye benzer ama C olmayan, benim “tarzanca” olarak adlandırdığım bir dil ile kodları önce anlayabileceğim şekilde yazdım. For’lu if’li şekillerde, değişken kullanarak. Sonra ikinci defa kodların üstünden geçerek, bunları ASM’ye “derledim”.

Böyle yapınca, kendimi daha üst seviyeli bir dilde yazıyor gibi hissettim kodları. Projeye etkinlikten puan verilmeyecek olması da bu isteğimi gerçekleştirmemi sağladı. (Dördüncü ödev ne kadar sonsuz döngüye giriyormuş gibi dursa da, emu8086’da çalıştırırsanız 15 dakika sonra program bitiyor, doğru da çözüyor. 😀 )

Kodları emu8086 emulatörünün dördüncü sürümünde sorunsuzca çalıştırabilirsiniz.

Gelgelim proje metnine ve çözümlerime…

Eğer kodları indirmeden incelemek isterseniz yazının devamına bakabilirsiniz.

Ödev 1: Palindromlar

Projenin ilk kısmında başlangıç adresi SI’da olan, data segmentteki bir metnin içindeki kelimelerin kaç tanesinin palindrom olduğunun sayısı isteniyordu. Benim kodumda bu sayı CX registerından alınabilir.

DİKKAT: Palindrom ASM’si bazen hatalı sonuçlar göndermekte olup, çalışmak için kullanılmaması şiddetle önerilir. Hatayı yakalayan olup da bana haber verirse çok mutlu olurum.

; UMUT BENZER
; 05-06-7670
; https://ubenzer.com/
; SURUM 2
data segment
   character  dw ?    ; En son islenen karakterin pointerini tutar
   palindrom  dw 0    ; Kac tane palindrom kelime bulundugunu tutar
   simdiki_cumlenin_karakter_sayisi dw 0 ; Process edilen kelimede kac harf oldugunu tutar.
   curr_palindrom db 0   ; Process edilen kelime palindromsa 0, degilse 1
   cumle_baslangici dw ? ; Process edilen kelimenin baslangic pointeri
   karsilastirilacak dw ? ; Process edilen kelimede karsilastirilacak harf sayisi
   son_kelime_mi db 0
   cumle db ' . A A. AA ABA ABBA ADA ADDA A A REM UMUT BENZER SCORPIONS BILMUH DENEME.DENEME  DENEME DENEEEEME PALINDROM 123 121 DENEME ASA A $ DOLARDAN $ SONRA ABBA REM SCORPIONS VS.'
ends

code segment
 start:
   MOV ax, data
   MOV ds, ax
   MOV es, ax
   
   MOV SI, OFFSET cumle   
   MOV character, OFFSET SI    
   
 enbas:
   MOV simdiki_cumlenin_karakter_sayisi, 0
   MOV curr_palindrom, 0
   MOV AX, character
   MOV cumle_baslangici, AX
   
   karakter_sayma_basladi:
   MOV BX, character
   
   MOV AX, SI[BX]
   SUB AL, '$'
   JZ son_kelime    
   
   MOV AX, SI[BX]
   SUB AL, ' '
   JZ karakter_sayma_bitti
   
   MOV AX, SI[BX]
   SUB AL, '.'
   JZ karakter_sayma_bitti   
   
      INC simdiki_cumlenin_karakter_sayisi
      INC character;
      JMP karakter_sayma_basladi
   
   son_kelime:
      MOV son_kelime_mi, 1
      MOV curr_palindrom, 1
   
   karakter_sayma_bitti:
                       
      MOV DX,0
      MOV AX,simdiki_cumlenin_karakter_sayisi
      CMP AX,1   
      JNZ bir_karakter_degil
     
         INC palindrom
         INC character
         JMP karakter_sarma_basladi
      
      bir_karakter_degil:   
      CMP AX,0
      JNZ sifir_karakter_degil
         INC character;
         JMP karakter_sarma_basladi
         
      sifir_karakter_degil:         
      MOV BX, 2
      DIV BX
      MOV karsilastirilacak, AX
      
   ; for
   MOV CX, 0             
   
   palindrom_mu_dongusu: 
      MOV BX, karsilastirilacak
      SUB BX,CX
      JZ palindrom_mu_dongusu_bitti
         ; if
         MOV BX, cumle_baslangici
         ADD BX, CX         
         MOV AX, SI[BX] 
         
         MOV BX, cumle_baslangici
         ADD BX, simdiki_cumlenin_karakter_sayisi
         SUB BX, 1 ; Ilk eleman 0.indis ile basladigi icin
         SUB BX, CX
         MOV DX, SI[BX]        
         
         SUB AL, DL         
         JZ palindrom_mu_dongusu_sonu   
        
            MOV curr_palindrom, 1
            MOV CX,karsilastirilacak
            DEC CX
          
         ;end if
         palindrom_mu_dongusu_sonu:  
      INC CX
      JMP palindrom_mu_dongusu:          
   palindrom_mu_dongusu_bitti:
   ; endfor
  
   MOV AL, curr_palindrom
   SUB AL, 0
   JNZ palindrom_degil
       INC palindrom
   
   palindrom_degil:
   
   ;bitti mi kontrol
   bitti_mi_kontrol:
   MOV BL, son_kelime_mi
   SUB BL, 1
   JZ bitirirken   
   
   ;bitmediyse bir sonraki kelimenin basina gidelim.
  
   karakter_sarma_basladi:
   MOV BX, character
   MOV AX, SI[BX]
   SUB AL, ' '
   JZ karakter_sar
   
   MOV AX, SI[BX]
   SUB AL, '.'
   JZ karakter_sar   

      JMP enbas
   
   karakter_sar:
      INC character;
      JMP karakter_sarma_basladi
        
 bitirirken:
   MOV CX, palindrom          
   MOV ax, 4c00h ; exit to operating system.
   INT 21h    
ends

end start ; set entry point and stop the assembler.

Ödev 2: EKOK

Verilen iki sayının en küçük ortak katının bulunması isteniyordu. (EKOK, LCM) Benim kodumda bu değer BX registerından alınabilir. Bu kodda prosedür çağrılması ve recursiona (öz yineleme) örnek bulunabilir.

; Umut Benzer
; 05-06-7670
; https://ubenzer.com/
data segment
   sayi1 dw 200
   sayi2 dw 70
ends

stack segment
    dw   128  dup(0)
ends

code segment
   gcd proc
   ; PARAMETRELER AX VE BX'ten alinip, sonuc BX'te verilir.
   CMP BX,0
   JNE bx_sifir_degil
     MOV BX, AX
     RET
   
 bx_sifir_degil:               
   MOV CX,BX
   MOV DX,0
   DIV BX
   MOV BX,DX
   MOV AX,CX    
   CALL gcd
   RET    
endp
   
start:
   MOV AX, data
   MOV DS, AX
   MOV ES, AX

   ; LCM = sayi1 * sayi2 / GCD(a,b)

   MOV AX, sayi1
   MOV BX, sayi2
   CMP AX, BX
   JG a_buyuk_b:
   ; Eger BX AX'ten buyukse yerlerini degistirelim.  
      MOV CX,BX
      MOV BX,AX
      MOV AX,CX
   a_buyuk_b:
   
   PUSH AX
   PUSH BX
   
   CALL gcd
   
   POP AX
   POP CX
   
   MUL CX
   DIV BX
   MOV BX,AX
      
   MOV AX, 4c00h
   INT 21h    
ends

end start

Ödev 3: Faktoriyel

Projenin üçüncü kısmında recursion kullanarak verilen bir sayının ASM’de bulunması isteniyordu. Benim ödevimde sonuç CX’ten alınabilir. Bu ödev 16 bit’ten daha büyük sonuçları doğru görüntülemez.

; Umut Benzer
; 05-06-7670
; https://ubenzer.com/
data segment
   sayi dw 0
ends

stack segment
    dw   128  dup(0)
ends
     
code segment
      
faktoriyel proc
    ; 0 faktoriyel ozel durumu
    CMP AX, 0
    JNE sifir_diil
    MOV BX, 1
    RET
    
    ; 1 faktoriyel base durum
    sifir_diil:
    CMP AX, 1
    JNE bir_diil
    MOV BX, 1
    RET
         
    ; Diger durumlar     
    bir_diil:
    PUSH AX
    DEC AX
    CALL OFFSET faktoriyel
    POP AX
    MUL BX
    MOV BX,AX
    RET                                                                                                                                                                                                                                                                                                                                                                                                   
endp

start:
   MOV AX, data
   MOV DS, AX
   MOV ES, AX

   MOV  AX, sayi
   MOV  CX, OFFSET faktoriyel
   CALL CX
    
   MOV CX, BX
   ; Sonuc BX ve CX'tedir.
   ; Program 16'bitten buyuk sonuclari dogru goruntuleyemez.

   MOV AX, 4c00h
   int 21h    
ends 
end start

Ödev 4: Parity Bitleri

Bu ödevde 100 baytlık bir tablonun (sütunlar bitler, satırlar baytlar) even parity bitlerinin bulunması isteniyordu. Bu kod aşırı uzun olmasına ve çok aşırı uzun sürede çalışmasına rağmen doğru bir hesaplama yapmakta olup, hem dikey hem yatay parityleri doğru bir şekilde hesaplamaktadır. Sonuç, ilgili bellek bölgesindeki değişiklikler izlenerek görülebilir.

DİKKAT: Bu ASM etkin değildir ve çok daha kısa sürede çalışabilecek kodlar yazılabilir. Sonuç doğru olmakla beraber bu kodun dikkate alınıp üzerinde çalışılmamasını şiddetle öneririm.

data segment
   ;bilgiler db 100 DUP(11111111B)
   bilgiler db 11110111B,01011110B,01011010B,10001000B,11111010B,11111111B,00000000B,10101000B,00101111B,01111010B, 90 DUP(11111111B), ?
   sayi equ 100
   i db ?
   parity db 0
   
ends

stack segment
    dw   128  dup(0)
ends

code segment
   
get_mask proc
     CMP CH,0
     JNE sifir_degil
       MOV DL, 10000000B ;MASK
     sifir_degil:
     CMP CH,1
     JNE bir_degil
       MOV DL, 01000000B ;MASK
     bir_degil:           
     CMP CH,2
     JNE iki_degil
       MOV DL, 00100000B ;MASK
     iki_degil:  
     CMP CH,3
     JNE uc_degil
       MOV DL, 00010000B ;MASK
     uc_degil:
     CMP CH,4             
     JNE dort_degil
       MOV DL, 00001000B ;MASK
     dort_degil:
     CMP CH,5           
     JNE bes_degil
       MOV DL, 00000100B ;MASK
     bes_degil:
     CMP CH,6 
     JNE alti_degil
       MOV DL, 00000010B ;MASK
     alti_degil:
     CMP CH,7
     JNE yedi_degil
       MOV DL, 00000001B ;MASK
     yedi_degil:   
     RET
endp 


start:
    mov ax, data
    mov ds, ax
    mov es, ax
    
    ; Once ROW parity bitleri
      
    ; for baslangici
    MOV CL, 0
    satir_gezintisi:                       
    CMP CL, sayi  ; DONGU SAYISI
    JE satir_gezintisi_bitti
    MOV i,CL 
    ; for baslangici 
       
       MOV SI, OFFSET bilgiler
       MOV CH,0
       ADD SI, CX             
       MOV AL, DS:[SI] ; Siradaki kelimeyi getir
       MOV parity, 0
       
       ; ikinci for baslangici
       MOV CH, 0
       ic_satir_gezintisi:                       
       CMP CH,7
       JE ic_satir_gezintisi_bitti
       ; for baslangici 
                   
           CALL get_mask
           
           ; Birinci karakter kontrolu
           AND AL,11111110B
           MOV BL,AL
           AND BL, DL ; APPLY MASK
                
                SUB BL, 0
                JZ problem_yok                      
                     ; Partiye gelecek olan degeri tersine cevir
                     MOV BH,parity
                     SUB BH,0
                     JNZ sifir_yap:               
                     MOV parity,1
                     JMP devam
                     sifir_yap:
                     MOV parity,0
                     devam:                                      
               problem_yok:
     
       
       ; for sonu
       INC CH
       JMP ic_satir_gezintisi
       ic_satir_gezintisi_bitti:
       ; for sonu
       
       OR AL, parity
       MOV DS:[SI],AL


    ; for sonu
    MOV CL,i
    INC CL
    JMP satir_gezintisi
    satir_gezintisi_bitti:
    ; for sonu
    
; COLUMN parity bitleri
    
    MOV SI, OFFSET bilgiler
    MOV BX, sayi ; DONGU SAYISI
    ADD SI, BX             
    MOV DS:[SI],0 ; Siradaki kelimeyi getir
       
       
    ; for baslangici
    MOV CH, 0
    sutun_gezintisi:                       
    CMP CH, 8
    JE sutun_gezintisi_bitti

    ; for baslangici 
       MOV parity, 1
           
       ; ikinci for baslangici
       MOV CL, 0
       ic_sutun_gezintisi:                       
       CMP CL, sayi ; DONGU SAYISI
       JE ic_sutun_gezintisi_bitti
       MOV i,CL
       ; for baslangici 
               
 
          MOV SI, OFFSET bilgiler
          MOV BL,CL
          MOV BH,0
          ADD SI, BX             
          MOV AL, DS:[SI] ; Siradaki kelimeyi getir
          
       
       
          CALL get_mask        
           
          ; Birinci karakter kontrolu
          MOV BL, AL
          AND BL, DL ; APPLY MASK
                
                SUB BL, 0
                JZ problem_yok_sutun                      
                     ; Partiye gelecek olan degeri tersine cevir
                     MOV BH,parity
                     SUB BH,0
                     JNZ sifir_yap_sutun:               
                     MOV parity,1
                     JMP devam_sutun
                     sifir_yap_sutun:
                     MOV parity,0
                     devam_sutun:                                      
               problem_yok_sutun:
     
       
       ; for sonu
       MOV CL,i
       INC CL
       JMP ic_sutun_gezintisi
       ic_sutun_gezintisi_bitti:
       ; for sonu
         
       CMP parity,0
       JNE degisiklik_gerekli_degil
       
       MOV SI, OFFSET bilgiler
       MOV BX, sayi
       ADD SI, BX
       OR DS:[SI],DL
          
                              
       degisiklik_gerekli_degil:                            
                                   

    ; for sonu
    
    INC CH
    JMP sutun_gezintisi
    sutun_gezintisi_bitti:
    ; for sonu    
    
    
    
    
    MOV ax, 4C00H ; exit to operating system.
    int 21H    
ends

end start ; set entry point and stop the assembler.

İyi günler

Mikro İşlemciler Projesi 6 yorum aldı.

  1. Merhaba Umut,
    C gibi yazmadan önce akış diyagramını çizmenizin faydası olacağını düşünüyorum. Gerçi bundan sonra ne zaman yazarsınız bilmem ama yine de söylemek gerek

    1. @Okan Bursa: Merhaba Hocam, finallere hazırlanırken flowchartlar ile kod yazmayı deneyeceğim, öneriniz için çok teşekkür ederim.

      @Canburak: İki sayının en küçük ortak böleninin bir olduğu konusundaki matematiksel ispatın için teşekkür ederim, ancak senin de yorumunun sonunda fark ettiğin üzere bu sadece bir yazım hatası olmuş. Yine de beni iki sayının ikisinin de en az bire bölünebileceği konusunda aydınlatlattığın için çok sağol, aklıma gelmeyebilirdi. Yazım hatasını düzeltiyorum. Tespit için tekrar tekrar teşekkürler, İtalya’ya sevgiler. (eğer doğru hatırlıyorsam)

  2. “Verilen iki sayının en küçük ortak böleninin bulunması isteniyordu. (EBOB) ”

    Böyle bir cümle kullanmışsın ancak bu cümle hatalı. EBOB -> En Büyük Ortak Bölen kavramının kısaltmasıdır en küçük değil. Zaten iki sayının en küçük ortak böleni eğer kümeyi sayma sayıları olarak alırsak 1 olur. Eğer tam sayılar kümesini düşünürsek bu durumda iki sayının EBOB unun toplama işlemine göre tersi bize en küçük ortak böleni verebilir.

    Neyse işin matematik kısmını boşver. Adlandırmada hata var.

  3. @Umut işin matematik kısmını can sıkıntısından yazmıştım. Sana bilmediğini ima etmek ya da bir şey öğretmek için değildi. Yanlış anlaşılma olduysa özür dilerim. İtalya konusunda da evet doğru hatırlıyorsun.

  4. oshansoftta 8085 similatörüneq basic complier ile bir proje yazmam lazım yılan yada trafik ışığı bu konuda bana yardımcı olabilirmisiniz çok acil

  5. meraba hocam emu 8086 da 16 bit lik bilgisayarda 0 dan 9 a kadar sayan sayıcı devresi 9 dan sonra tekrar başa dönüp tekrar 9 a kadar sayan bu şekılde tekrarlayan programı nasıl yazabiliriz teşekkürler şimdiden

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir