; 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