Question

So I've started learning 16 bit assembly using NASM on a Windows machine. If got this little program that I've created that asks the user for input and then determines if the input is within a certain range (0 to 9). If it is, it goes on to see if the value is divisible by three, if not it's supposed to loop and ask the user for another value. Here's my code:

org 0x100
    bits 16
;jump over data declarations
    jmp main

input:
    db 6
    db 0
user: times 6 db '  '

cr_lf: db 0dh, 0ah, '$'

message: db 'Please enter the number you select between 0 and 9:','$'
errormsg: db '***', 0ah, 0dh, '$'
finalMsg: db 'Number is divisible by 3!', 0ah, 0dh, '$'
finalErrorMsg: db 'Number is not divisible by 3!', 0ah, 0dh, '$'

outputbuffer: db '     ', '$'

;clear screen and change colours
clear_screen:
    mov ax, 0600h
    mov bh, 17h ;white on blue
    mov cx, 00
    mov dx, 184Fh
    int 10h
    nop
    ret

move_cursor:
    mov ah, 02
    mov bh, 00
    mov dx, 0a00h
    int 10h
    ret

;get user input
get_chars:
    mov ah, 01
    int 21h
    ret

;display string
display_string:
    mov ah, 09
    int 21h
    ret

errstar:
    mov dx, errormsg    
    call display_string
    int 21h
    jmp loop1

nextphase:
    cmp al, 30h     ;compare input with '0' i.e. 30h
    jl errstar      ;if input is less than 0, display error message
    ;else
    call ThirdPhase     ;input is clearly within range

ThirdPhase:
    xor dx, dx      ;set dx to 0 for the divide operation   
    ;at this point al has the value inputted by the user
    mov bl, 3   ;give bl the value
    div bl      ;divide al by bl, remainder stored in dx, whole stored in ax
    cmp dx, 0   ;compare remainder to 0
    jg notEqual ;jump to not divisible by three as remainder is greater than 0
    je end

notEqual:
    mov dx, finalErrorMsg
    call display_string
    int 20h

end:
    mov dx, finalMsg
    call display_string
    int 20h

;main section
main:
    call clear_screen   ;clear the screen
    call move_cursor    ;set cursor

loop1:
    mov dx, message     ;mov display prompt into dx 
    call display_string ;display message
    call get_chars      ;read in character
    ;at this point a character value is inputted by the user
    cmp al, 39h     ;compare with '9' i.e. 39h
    jle nextphase       ;if value is less than or equal to 9, move onto next phase
    jg errstar      ;else call error and loop

Anyway, so the value range checking works fine and the looping works fine too. The problem I've got is at the divisible in the three ThirdPhase section. My understanding is that firstly I need to make sure dx contains a value of 0. Then move the value 3 into bl. Now al contains the user input, bl contains the value 3, and dx is 0. Then during the div bl part, al is divided by bl which is the value of 3. The remainder is stored in dx and if compared to 0 and found to be greater then it should jump to notEqual section else jump to end section.

As it is now, I always get the finalMsg displayed, which is only supposed to be displayed if the value is completely divisible by 3.

Anyone have some suggestions. Thanks. JP.

Était-ce utile?

La solution

You are doing a div bl, which is dividing by a byte. So the quotient is in al and the remainder is in ah, not in ax and dx, respectively, as your code assumes. Make sure you clear ah before the div since your dividend is the single byte in al.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top