hw5_ex3.asm

; Jade Yu Cheng
; ICS 312
; Assignment 5 Exercise 3
; March 21, 2009

; The program prompt the user to enter 10 numbers between 0 and 9 (both
; included). The program prints an error message and re-prompt the user for
; another number if the number entered is invalid. These numbers are stored in
; memory as 1-byte values. The program computes a tally for each possible
; number.  The program prints a (crude) histogram of the numbers. Namely, the
; x-axis lists the possible numbers from 0 to 9, and bars are shown above each
; number to represent the tally (with the maximum bar height being 10, and the
; minimum bar being 0).

%include "asm_io.inc"

segment .data
        prompt          db      "Enter a number between 0 and 9: ", 0     ; prompt msg
        invalid         db      "Invalid number!", 0      ; invalid msg
        t               db      0, 0, 0, 0, 0, 0, 0, 0, 0, 0    ; counters
        buffer          db      "          "                    ; buffer for #s
        dash            db      "----------", 0
        number          db      "0123456789", 0

segment .bss
        n       resb    10      ; reserve space for the numbers

segment .text
        global asm_main
asm_main:
        enter   0,0             ; setup
        pusha                   ; setup

; This block of code prompts the user input in a loop and store them in n.
        mov     edx, 0          ; initialize edx = 0
        mov     ebx, n          ; initialize ebx to point to the starting of n
loop_input_start:
        cmp     edx, 9          ; compare edx with 9 and
        jg      loop_input_end  ; terminate the loop if 10 iterations are done

        mov     eax, prompt     ; print out the message to prompt user input
        call    print_string
        call    read_int        ; read a number and store it in eax
        cmp     eax, 0          ; compare the input with 0
        jnge    near else_block ; branch if the input is a negative number
        cmp     eax, 9          ; compare the input with 9
        jnbe    near else_block ; branch if the input is larger than 9
        mov     [ebx], al       ; store the number as one byte quantity in ebx

        inc     edx             ; increment loop count edx
        inc     ebx             ; increment ebx to point to the next position
        jmp     loop_input_start
loop_input_end:

; This block of code counts the occurences of inputs and store them in t.
        mov     dl, 0           ; initialize dl = 0
        mov     ebx, n          ; initialize ebx to point to the starting of n
loop_count_start:
        cmp     dl, 9           ; compare dl with 9 and jump if dl is greater
        jg      loop_count_end

        mov     ecx, t          ; let ecx points to the beginning of t
        movzx   eax, byte [ebx] ; extend item as a byte into eax
;        mov     al, [ebx]       ; store the currently examined number in al
;        movzx   eax, al         ; unsigned extend this number to be 4 bytes
        add     ecx, eax        ; move ecx ptr to a corresponding position in t
        inc     byte [ecx]      ; increment the corresponding counter in t

        inc     ebx             ; increment ebx to point ot the next position
        inc     dl              ; increment dl the loop counter
        jmp     loop_count_start
loop_count_end:

; The inner loop populates "buffer" to be either "#" or " ".  The outer loop
; print out "buffer" from the top row to the bottom row.
        mov     dl, 10          ; initialize dl = 0
loop_outer_start:
        cmp     dl, 1           ; compare dl with 1
        jl      end_print       ; ends the outer loop if 10 iterations are done

        mov     dh, 0           ; initialize dh = 0
loop_inner_start:
        cmp     dh, 9           ; compare dh with 9
        jg      loop_inner_end  ; ends the inner loop if 10 iterations are done

        mov     ebx, t          ; let ebx points to the starting of t
        mov     ecx, buffer     ; let ecs points to the starting of buffer
        movsx   eax, dh         ; signed extend dh to eax
        add     ebx, eax        ; let ebx points to the dh's index in t
        inc     dh              ; increment dh the inner loop counter
        cmp     [ebx], dl       ; compare the corresponding item in t with dl
        jl     loop_inner_start ; don't do anything if item is smaller than dl

        add     ecx, eax        ; otherwise go to the dh's index of buffer
        mov     byte [ecx], 35  ; change it from " " to "#"
        jmp     loop_inner_start
loop_inner_end:
        push    buffer          ; pass in the buffer as the parameter to print
        call    print_buffer    ; call the function and push this address
        call    print_nl        ; start a new line for each row of buffer
        add     esp, 4          ; pop the only param off the stack

        dec     dl              ; decrement dl the outer loop counter
        jmp     loop_outer_start

; This is a function to print out an array of charactors.
print_buffer:
        push    ebp             ; store the old ebp
        mov     ebp, esp        ; use ebp to store the current top of the stack
        mov     ecx, [ebp + 8]  ; move the only param to ecx
        mov     dh, 0           ; print out the contents in a loop
loop_print_start:
        cmp     dh, 9
        jg      loop_print_end  ; ends the loop if 10 items are printed

        mov     al, [ecx]       ; print out the item in the buffer array
        call    print_char
        mov     byte [ecx], 32  ; erase and replace with " " after printing

        inc     ecx             ; increment ecx to point to the next item
        inc     dh              ; increment the loop counter
        jmp     loop_print_start
loop_print_end:
        pop     ebp             ; pop off ebp to clean up the stack
        ret                     ; pop off the address and jump there

; This block of code prints out invalid input message and jump back to the
; user input loop for more inputs.
else_block:
        mov     eax, invalid    ; print out the number invalid message
        call    print_string
        call    print_nl
        jmp     loop_input_start; go back to the loop for more inputs

; This block of code prints out the bottom two rows and ends the program
end_print:
        mov     eax, dash
        call    print_string
        call    print_nl
        mov     eax, number
        call    print_string
        call    print_nl

; This is the clean up code
        popa                    ; cleanup
        mov     eax, 0          ; cleanup
        leave                   ; cleanup
        ret                     ; cleanup
Valid HTML 4.01 Valid CSS