Kompiuterių architektūra/Antroji praktinė užduotis/Fibonačio skaičiai

Iš MIF SA Wiki.

Peršokti į: navigaciją, paiešką
;Programa randa N-tąjį fibonačio skaičių
.model small
.stack 100h
 
dydis            equ    20
 
.data
    duom        db    100 dup (0)
    rez        db    100 dup (0)
    handleIn    dw    ?
    handleOut    dw    ?
    buffer        db    dydis dup ('?')
    err1        db    "Klaida: nepavyko atidaryti duomenu failo"      
    err2        db    "Klaida: nepavyko atidaryti rezultato failo"    
    err3        db    "Klaida: nepavyko nuskaityti is duomenu failo"  
    err4        db    "Klaida: nepavyko irasyti i rezultato faila"    
    err5        db    "Klaida: nepavyko uzdaryti duomenu failo"       
    err6        db    "Klaida: nepavyko uzdaryti rezultato failo"     
 
        apie        db    "Gediminas Zukas, Programu sistemos, I kursas, 4 grupe", 13, 10  
            db    "2.28: Programa, kuri randa n-taji Fibonacio skaiciu", 13, 10, 13, 10 
            db    "FIB [/?] input output", 13, 10, 13, 10
            db    "  /?", 9, 9, "sis pagalbos pranesimas", 13, 10
            db    "  input", 9, 9, "duomenu failo pavadinimas", 13, 10
            db    "  output", 9, "rezultato failo pavadinimas", 13, 10
    ppask        dw    0
    pask        dw    1
    ntasis        dw    ?
    ats        db    5 dup('?')
 
.code
start:
    mov    ax, @data
    mov    ds, ax
 
       mov    bx, 81h
        xor    si, si
       xor    di, di
 
    parametras:
        mov    ax, es:[bx]
        cmp    al, 13d
        je    programa
        cmp    ax, '?/'
        je    pagalba
 
            input:
                mov    ax, es:[bx]
                cmp    al, ' '
            je    output
            cmp    al, 13d            ; nenurodytas rezultato failas -> pagalba
                     je    pagalba
            mov    [duom + si], al
            inc    si 
            inc    bx
            jmp    input
 
               output:
            inc    bx            ; kadangi pirmas simbolis parametruose visada tarpas
            cmp    bx, 82h            ; tai ziurim ar tai sis atvejis, jei taip - grisim kai bus antras tarpas
            je    parametras
            mov    ax, es:[bx]
            cmp    al, 13d
            je     programa
            mov    [rez + di], al
            inc    di
            jmp    output
 
    pagalba:
        mov    dx, offset apie
        mov    cx, 240d
        call    print
        jmp    pabaiga
 
        programa:
        cmp    duom, 0
        je    pagalba
        cmp    rez, 0
        je    pagalba
 
        mov    al, 00h
        mov    ah, 3dh
        mov    dx, offset duom
        int    21h
        jc    klaida1            ; klaida atidarant duomenu faila
        mov    handleIn, ax
 
        xor    cx, cx
        mov    ah, 3ch
        mov    ch, 00h
        mov    dx, offset rez                  
        int    21h  
        jc    klaida2            ; klaida atidarant rezultato faila    
        mov    handleOut, ax
 
        mov    ah, 3fh
        mov    cx, 10
        mov    bx, handleIn
        mov    dx, offset buffer
        int    21h    
        jc    klaida3            ; klaida skaitant is duomenu failo
        mov    dh, al            ; DH := nuskaitytu baitu kiekis
 
        mov    bx, offset buffer
        mov    cl, 10
        xor    dl, dl
        xor    ax, ax
 
    ; @return   AX = skaicius
    StrToInt:
        mov    dl, [bx]        ; gauname simboli
        cmp    dh, 0            ; ar dar ne pabaiga?
        je    skaiciuoti               
        mul    cl            ; AX := AX (aka rezultatas) * 10
        sub    dl, '0'
        add    al, dl            ; AL := AL + skaicius
        inc    bx
        dec    dh 
        jmp    StrToInt
 
        ; -------- error handler #1 ---------
    klaida1:
        mov    dx, offset err1
        mov    cx, 40
        call    print
        jmp    pabaiga       
    klaida2:
        mov    dx, offset err2
        mov    cx, 42
        call    print
        jmp    pabaiga
    klaida3:
        mov    dx, offset err3
        mov    cx, 44
        call    print
        jmp    pabaiga        
    ; -----------------------------------
 
    skaiciuoti:
        mov    cx, ax
 
        cmp    cx, 1
        je    return_0
        cmp    cx, 2
        je    return_1
 
        ; 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765 ..        
        ; @parameter    CX = ieskomo nario numeris
        ; @return       ntasis = fibonacio skaicius
 
        fibonatis:          
            mov    ax, [ppask]             ; AX := priespaskutinis
            mov    bx, [pask]              ; BX := paskutinis
            add    ax, bx                  ; AX := priespaskutinis + paskutinis
 
            mov    [ntasis], ax            ; n-tasis narys := AX (aka priespaskutinis + paskutinis)
            mov    [ppask], bx             ; priespaskutinis := paskutinis
            mov    [pask], ax              ; paskutinis := n-tasis narys
 
            dec    cx
            cmp    cx, 2            ; 2, nes pradedam skaiciuot nuo trecio
            jg    fibonatis
 
 
        mov    cx, 10        
        mov    dx, '*'                ; * - zymi pabaiga
        push    dx
        xor    dx, dx
        xor    bx, bx
 
        jmp    return_N
 
        return_0:
            mov    [ats], '0'
            mov    bx, 1
            jmp    rezultatas
 
        return_1:
            mov    [ats], '1'
            mov    bx, 1
            jmp    rezultatas
 
        return_N:
            mov    ax, [ntasis]
 
 
        konvertuoti:
            div    cx
            push    dx
            xor     dx, dx
            cmp    ax, 0
            jne    konvertuoti
 
        ciklas: 
            pop    ax
            cmp    ax, '*'
            je    rezultatas            
            mov    [ats + bx], al
            add    [ats + bx], '0'
            inc    bx            
            jmp    ciklas
 
        rezultatas:
            mov    ah, 40h
            mov    cx, bx
            mov    bx, handleOut
            mov    dx, offset ats
            int    21h            
            jc    klaida4            ; klaida irasant i rezultato faila
 
            mov    ah, 3eh
            mov    bx, handleIn
            int    21h        
            jc    klaida5            ; klaida uzdarant duomenu faila
 
            mov    ah, 3eh
            mov    bx, handleOut
            int    21h            
            jc    klaida6            ; klaida uzdarant rezultato faila
 
            jmp    pabaiga
 
            ; -------- error handler #2 ---------
        klaida4:
            mov    dx, offset err4 
            mov    cx, 42
            call    print
            jmp    pabaiga
        klaida5:
            mov    dx, offset err5
            mov    cx, 39
            call    print
            jmp    pabaiga
        klaida6:
            mov    dx, offset err6
            mov     cx, 41
            call     print
            jmp    pabaiga
        ; -----------------------------------
 
    pabaiga:        
        mov    ax, 4c00h
        int    21h
 
; spausdinti, naudojant int 21,40
; @parameter    CX = spausdinamu bitu kiekis
print   PROC
    push    bx
    mov    bx, 1
    mov    ah, 40h
    int    21h
    pop    bx
    ret
print   ENDP
 
end start
Asmeniniai įrankiai