; 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