hw6_ex4.asm

; Jade Yu Cheng
; ICS 312
; Assignment 6 Exercise 3
; April 9, 2009

; This program prompts the user to enter a signed 32-bit integer. The program
; prints out the binary representation of the integer.  The user is prompted
; for a motif after the binary representation of the integer is printed.
; Program prints out the number of times the user specified motif occurs in the
; binary representation of the entered number.

%include "asm_io.inc"

segment .data
        msg1    db      "Enter an integer: ", 0                 ; msg1
        msg2    db      "The binary representation is: ", 0     ; msg2
        msg3    db      "The number of motifs is: ", 0          ; msg3
        msg4    db      "Enter a binary motif: ", 0             ; msg4
        msg5    db      "Invalid input.", 0                     ; msg5
        counter dd      0                                       ; motif counter
        len     dd      0                                       ; size of motif
        motif   dd      0       ; space for a maximum of 32 bit motif number
        bitmask dd      0       ; e.g., it's 0..011 for motif 00, 01, 10, or 11

segment .bss
        binary          resb    32      ; space to store binary representation
        input           resd    1       ; space for the 32 bit input number
        iterations      resd    1       ; number of loops needed to find motif

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

;;; prompt the user the enter a number and treat it as a 32 bit number.
        mov     eax, msg1       ; print out the prompt message.
        call    print_string
        call    read_int        ; read a number and store in eax
        mov     [input], eax    ; store the input number into input

;;; convert the number to its binary and store it in binary..
convert:
        mov     ebx, binary     ; ebx points to binary
        add     ebx, 31         ; ebx points to the last bit of binary
convert_loop:
        cmp     ebx, binary - 1 ; terminate when all 32 bits are written
        je      convert_loop_end
        shr     eax, 1          ; right shift by 1, equavilent as divide by 2
        jc      write_one       ; if carry flag is set wirte 1 to ebx
        mov     [ebx], byte 0   ; otherwise wirte 0 to ebx
        dec     ebx             ; decrement ebx to the next spot to write to
        jmp     convert_loop
write_one:
        mov     [ebx], byte 1   ; write 1 to ebx
        dec     ebx             ; decrement ebx to the next spot to write
        jmp     convert_loop
convert_loop_end:

;;; print out binary
print:
        mov     eax, msg2       ; print out the second message
        call    print_string
        mov     ebx, binary     ; let ebx points to binary
print_loop:
        cmp     ebx, binary + 32; terminate when it reaches the end
        je      print_loop_end
        mov     eax,0           ; clean up eax
        mov     al, [ebx]       ; move the bit in eax
        call    print_int       ; print it out
        inc     ebx             ; increment the pointer to the next spot
        jmp     print_loop
print_loop_end:
        call    print_nl        ; print a blank line

;;; prompt user to enter a binary motif and store it as a 32 bit number. Wild
;;; cards are treated as 0s.  Meanwhile create a 32 bit long mask to turn off
;;; bits in input that do not concern.  E.g., motif 1*1's mask is 0..0101.
motif_block:
        mov     eax, msg4       ; print out the message to prompt user input
        call    print_string
        call    read_char       ; absorb the enter key stroke left by read_int
        mov     bl, 0           ; get at most 32 bit long user input
motif_loop:
        cmp     bl, 33
        je      invalid_input   ; input that's longer than 32 bits is invalid
        inc     bl
        call    read_char       ; obtain the character
        cmp     eax, 10         ; terminiate if it's the enter key
        je      motif_loop_end
        shl     dword [motif], 1; otherwise left shift the motif and mask by 1
        shl     dword [bitmask], 1
        inc     dword [len]     ; increment length count
        cmp     eax, 42         ; do not increment motif if the input is *
        je      motif_loop
        inc     dword [bitmask] ; increment bit mask if input is not *
        cmp     eax, 48         ; do not increment motif if the input is 0
        je      motif_loop
        cmp     eax, 49         ; increment motif by 1 if the input is 1
        jne     invalid_input   ; ortherwise it's a invalid input
        inc     dword [motif]   ; increment of motif by 1 if the input is 1
        jmp     motif_loop      ; read the next character
invalid_input:
        mov     eax, msg5       ; print error message and exit
        call    print_string
        call    print_nl
        jmp     end
motif_loop_end:

;;; find out the incidence of the user specified motif.
        mov     eax, 33         ; compute the iterations number
        sub     eax, [len]      ; there will be 32 - [len] + 1 times iterations
        mov     [iterations], eax
find_loop_start:
        mov     ecx, [input]    ; let ecx contain the value of input number
        mov     ebx, [motif]    ; let ebx contain the value of motif number
        mov     edx, 0          ; loop 32 - [len] + 1 times
find_loop:
        cmp     edx, [iterations]
        je      find_loop_end
        mov     eax, ecx        ; eax hold temporally input number
        and     eax, [bitmask]  ; turn off the first series of bits
        shr     ecx, 1          ; right shift ecx to examine the next set
        inc     edx             ; increment loop counter
        cmp     eax, ebx        ; compare motif with modified input
        jne     find_loop
        inc     dword [counter] ; increment counter if it's a match
        jmp     find_loop
find_loop_end:

;;; print out the incidence of the user specified motif
        mov     eax, msg3       ; print out message 3
        call    print_string
        mov     eax, [counter]
        call    print_int       ; print out the counter value
        call    print_nl

;;; clean up code
end:
        popa                    ; cleanup
        mov     eax, 0          ; cleanup
        leave                   ; cleanup
        ret                     ; cleanup
Valid HTML 4.01 Valid CSS