All pastes #925938 Raw Edit

Mine

public text v1 · immutable
·published 2008-03-03 12:44 UTC
rendered paste body
;********************
; Svar på oblig2
;
; author: Yngve Ådlandsvik
;
;********************
max_l   EQU 20			;Maksimal lengde på rekke

segment stack stack
        resb 64 
stacktop:

segment data
table:
        dw 20,-10, 30, 30, 40, 10, 45,-10,-60, 20, 30 
        dw 45, 20,-10, 15, 25,-34,-15, 20,-10, 18, -4
result:
        resw max_l
        
num_rows:
        dw 0
num_cols:
        dw 0
row_one:
        dw 0
row_two:
        dw 0
col_start:
        dw 0
col_end:
        dw 0
        
message_ant_rekker:
        db 'Skriv inn tal rekker: $'
message_ant_kolonner:
        db 'Skriv inn tal heiltal i kvar rekke: $'
message_rekker:
        db 'Skriv inn nr. på rekkene: $'
message_kolonner:
        db 'Skriv inn nr. på kolonnene: $'
message_resultat:
        db 'Resultatet er: $'
message_crlf:
        db 13, 10, '$'
print_number_buffer:
        resb 5
        db '$'
        
..start:
        ; initialiserer data- og stacksegmentregisterne
        mov ax, stack
        mov ss, ax
        mov sp, stacktop
        
        mov ax, data
        mov ds, ax

        ; skriver ut melding og leser inn antall rekker
        mov dx, message_ant_rekker
        mov ah, 9
        int 0x21

        call read_number
        mov [num_rows], ax

        call print_lf
       
        ; skriver ut melding og leser inn antall kolonner
        mov dx, message_ant_kolonner
        mov ah, 9
        int 0x21

        call read_number
        mov [num_cols], ax

        call print_lf

main_loop:
        ; skriver ut melding og leser inn de to rekkenumrene
        mov dx, message_rekker
        mov ah, 9
        int 0x21
        
        call read_number
        ; om første nummer er null, exit
        cmp ax, 0
        je  .exit
        mov [row_one], ax
        call read_number
        mov [row_two], ax
        call print_lf
        
        ; skriver ut melding og leser inn start- og sluttkolonne
        mov dx, message_kolonner
        mov ah, 9
        int 0x21
        
        call read_number
        mov [col_start], ax
        call read_number
        mov [col_end], ax
        call print_lf
        
        ; regner ut resultat-tabellen
        call calc_result
        
        ; regner ut antall verdier som skal skrives ut (slutt - start + 1)
        mov ax, [col_end]
        sub ax, [col_start]
        inc ax
        
        ; skriver ut resultatet
        call print_result

        jmp main_loop
        
        ; avslutter program, statuskode 0
.exit:
        mov ax, 0x4c00
        int 0x21

; Regner ut resultat-tabellen ved å sammenligne et subsett av to rader og
; å velge ut det høyeste nummeret
;
; input:
;       ingenting
; output:
;       ingenting
;
calc_result:
        ; tar vare på registre
        pusha
        
        mov cx, [col_start]
.loop:
        ; leser første nummer fra tabell
        mov ax, cx
        mov bx, [row_one]
        call read_table
        mov dx, ax
        
        ; leser andre nummer fra tabell
        mov ax, cx
        mov bx, [row_two]
        call read_table
        
        ; sammenligner de to tallene, resultatet havner i ax
        cmp ax, dx
        jg .noswap
        mov ax, dx
.noswap:

        ; regner ut hvor i resultat-tabellen vi skal plassere tallet
        mov bx, cx
        sub bx, [col_start]
        ; vi jobber med words, så dobler offsetet
        sal bx, 1
        ; skriver tallet til resultat-tabellen
        mov [result+bx], ax
        
        ; sjekker om vi er ferdig
        inc cx
        cmp cx, [col_end]
        jbe .loop
        
        ; gjenoppretter registre, returnerer
        popa
        ret

; Leser et tall fra tabellen i minnet
;
; input:
;       AX  kolonnenummer, starter på 1
;       BX  rekkenummer, starter på 1
; output:
;       AX  tallet fra tabellen
;
read_table:
        ; tar vare på registre
        push bx
        push cx
        push dx
        
        ; bytter om kolonne og rekke
        xchg ax, bx
        
        ; gjør om til 0-baserte indexer
        dec ax
        dec bx
        
        ; ganger rekkenummer med antall kolonner for å finne start-indexen til rekken
        mov cx, [num_cols]
        mul cx
        
        ; legger sammen index og kolonnenummer for å finne tallets posisjon
        add bx, ax
        
        ; vi jobber med words, så dobler offsetet
        sal bx, 1
        
        ; leser tallet fra minne
        mov ax, [table + bx]
        
        ; gjenoppretter registre, returnerer
        pop dx
        pop cx
        pop bx
        ret
        
; Leser et nummer fra stdin
; Takler bare positive nummer og ignorerer overflow
;
; input:
;       ingenting
; output:
;       AX  nummer lest
;       DL  første tegn etter nummer
;
read_number:
        ; tar vare på registre
        push bx
        push cx
        push dx
        
        mov bx, 0
.loop:  
        ; leser et tegn og sjekker om det er et siffer
        mov ah, 1
        int 0x21
        cmp al, '0'
        jb .done
        cmp al, '9'
        ja .done
        
        ; konverterer ascii-siffer til nummer
        sub al, '0'
        mov cl, al
        
        ; ganger oppsamlet nummer med 10, legger til det nye sifferet
        mov ch, 0
        mov ax, bx
        mov bx, 10
        mul bx
        add ax, cx
        mov bx, ax
        jmp .loop
        
.done:  
        ; gjenoppretter registre, plasserer returverdi i korrekt register
        pop dx
        mov dl, al
        mov ax, bx
        pop cx
        pop bx
        ret

; Skriver ut resultat-tabellen
;
; input:
;       AX  antall nummer i resultat-tabellen
; output:
;       ingenting
;
print_result:
        ; tar vare på registre
        pusha
        
        mov dx, ax
        ; offset starter på null
        mov cx, 0
        
.loop:
        mov bx, cx
        ; vi jobber med words, så dobler offsetet
        sal bx, 1
        
        ; leser nummeret fra minne
        mov ax, [result + bx]
        ; skriver det ut
        call print_number
        
        ; skriver ut et mellomrom mellom numrene
        push dx
        mov ah, 2
        mov dl, 32
        int 0x21
        pop dx
        
        ; sjekker om vi er ferdig, hvis ikke looper vi
        inc cx
        cmp cx, dx
        jne .loop
        
        ; skriver ut linjeskift på slutten
        call print_lf
        
        ; gjenoppretter registre, returnerer
        popa
        ret
        
; Skriver ut et linjeskift
;
; input:
;       ingenting
; output:
;       ingenting
;
print_lf:
        ; tar vare på registre
        push ax
        push dx
        
        ; skriver ut linjeskift
        mov ah, 2
        mov dl, 10
        int 0x21
        
        ; gjenoppretter registre, returnerer
        pop dx
        pop ax
        ret
        
; Skriver et nummer til stdout
; Takler både positive og negative nummer, fjerner unødvendige nuller
;
; input:
;       AX  nummeret som skal skrives ut
; output:
;       ingenting
;

print_number:
        ; tar vare på registre
        push ax
        push bx
        push cx
        push dx
        
        cmp ax, 0
        jge .notneg
        
        ; om nummeret er negativt skriver vi først ut et minustegn
        mov bx, ax
        mov dl, '-'
        mov ah, 2
        int 0x21
        ; så konverterer vi nummeret til et positivt
        mov ax, bx
        xor ax, 0xffff
        inc ax
        
.notneg:
        mov bx, 5
.loop:
        ; bruker rest etter divisjon til å lese et og et siffer
        mov dx, 0
        mov cx, 10
        div cx
        add dl, '0'
        ; lagrer sifrene i et midlertidig buffer
        mov [print_number_buffer+bx-1], dl
        ; abryter loopen om det ikke er flere sifre å hente
        cmp ax, 0
        je .done
        dec bx
        jnz .loop

.done:
        ; skriver ut det konverterte nummeret
        lea dx, [print_number_buffer+bx-1]
        mov ah, 9
        int 0x21
        
        ; gjenoppretter registre, returnerer
        pop dx
        pop cx
        pop bx
        pop ax
        ret