Reputation: 11
I'm having a problem with this code.
.model small
.stack 100h
.data
Msg1 DB 'Enter first number: $'
Msg2 DB 10, 13, 'Enter second number: $'
Msg3 DB 10, 13, 'Entered numbers are: $'
PositiveMsg DB ' is positive$'
NegativeMsg DB ' is negative$'
InputBuffer DB 6 DUP('$')
.code
main proc
mov ax, @data
mov ds, ax
; Display message asking for the first number
mov ah, 09h
lea dx, Msg1
int 21h
; Read the first number from the user
mov ah, 01h
int 21h
sub al, '0' ; Convert ASCII character to its corresponding numeric value
mov bh, al ; Move the numeric value of the first number to BH
; Determine if the first number is positive or negative
cmp al, 0
jge FirstPositive
mov dx, OFFSET NegativeMsg ; Display negativity message for the first number
int 21h
neg bh ; Negate the value to make it positive
jmp CheckSecondNumber
FirstPositive:
mov dx, OFFSET PositiveMsg ; Display positivity message for the first number
int 21h
CheckSecondNumber:
; Display message asking for the second number
mov ah, 09h
lea dx, Msg2
int 21h
; Read the second number from the user
mov ah, 01h
int 21h
sub al, '0' ; Convert ASCII character to its corresponding numeric value
mov dh, al ; Move the numeric value of the second number to DH
; Determine if the second number is positive or negative
cmp al, 0
jge SecondPositive
mov dx, OFFSET NegativeMsg ; Display negativity message for the second number
int 21h
neg dh ; Negate the value to make it positive
jmp DisplayNumbers
SecondPositive:
mov dx, OFFSET PositiveMsg ; Display positivity message for the second number
int 21h
DisplayNumbers:
; Display message indicating the entered numbers
mov ah, 09h
lea dx, Msg3
int 21h
; Display the first entered number
mov dl, bh ; Move the numeric value of the first number to DL
add dl, '0' ; Convert numeric value to its corresponding ASCII character
mov ah, 02h
int 21h
; Display the positivity/negativity message for the first number
mov dx, OFFSET PositiveMsg
int 21h
; Display a comma between the numbers
mov dl, ','
int 21h
; Display the second entered number
mov dl, dh ; Move the numeric value of the second number to DL
add dl, '0' ; Convert numeric value to its corresponding ASCII character
mov ah, 02h
int 21h
; Display the positivity/negativity message for the second number
mov dx, OFFSET PositiveMsg
int 21h
; Exit program
mov ah, 4Ch
int 21h
main endp
end main
This is the Msg3 which is wrong output. It should shows the input numbers and determine whether its positive or negative:
I already try different codes for that but the output for Msg3 is still wrong.
Upvotes: 0
Views: 89
Reputation: 39516
The messed-up output is mainly due to not specifying the required function number AH=09h before invoking DOS to print a message, and to using DH for holding the second number while at the same time you use DX for another purpose. Remember that the 16-bit DX is composed of the two 8-bit parts DH and DL.
The DOS.GetCharacter function 01h first waits for the user to press a keyboard key, then it writes the corresponding character on the screen, and finally it returns to your program with the key's ASCII code in the AL register. For some special keys the function will return AL=0, that way signaling that your program should invoke the function again so as to obtain the key's scancode.
If you want the user to be able to input a signed single-digit decimal number, so in the range [-9,9], you will have to take a two-step approach. If the first time that you use the function you already receive a digit [0,9] then you can just bypass the second step. If on the other hand the first character that you received happened to be a minus character then you must invoke the function a second time expecting a digit [0,9], and this time you must also negate the number.
Next simplified example validates the user input:
ReDo1:
mov ah, 01h ; DOS.GetCharacter
int 21h ; -> AL
sub al, '0'
cmp al, 10
jb GotIt ; Is positive [0,9]
cmp al, '-' - '0'
jne ReDo1 ; An invalid character detected
ReDo2:
mov ah, 01h ; DOS.GetCharacter
int 21h ; -> AL
sub al, '0'
cmp al, 10
jae ReDo2 ; Not a decimal digit
neg al
GotIt:
You don't want to repeat yourself too much (DRY), so you should put the above in a subroutine.
mov dx, OFFSET Msg1 ; Read the first number from the user
call Input ; -> AL (AH)
mov bl, al
mov dx, OFFSET Msg2 ; Read the second number from the user
call Input ; -> AL (AH)
mov bh, al
...
; IN (dx) OUT (al) MOD (ah)
Input:
mov ah, 09h ; DOS.PrintString
int 21h
ReDo1:
mov ah, 01h ; DOS.GetCharacter
int 21h ; -> AL
sub al, '0'
cmp al, 10
jb GotIt ; Is positive [0,9]
cmp al, '-' - '0'
jne ReDo1 ; An invalid character detected
ReDo2:
mov ah, 01h ; DOS.GetCharacter
int 21h ; -> AL
sub al, '0'
cmp al, 10
jae ReDo2 ; Not a decimal digit
neg al
GotIt:
ret
It is not sufficient to just add '0' and have DOS display the one character. A test for negative is in order and if required the output of a minus character:
test bl, bl
jns IsPositive
mov dl, '-'
mov ah, 02h ; DOS.PrintChar
int 21h
neg bl
IsPositive:
lea dx, [bx + '0'] ; BH and DH are un-important here
mov ah, 02h ; DOS.PrintChar
int 21h
Displaying the final summarizing message can benefit from using a subroutine too. I did include the necessary logic to differentiate between your PositiveMsg and NegativeMsg messages, something that you forgot to do:
mov dx, OFFSET Msg3 ; BL contains first number
call Output ; -> (AX BL DX)
mov bl, bh ; Load second number in BL
mov dx, OFFSET Msg4 ; Make this a ', $'
call Output ; -> (AX BL DX)
...
; IN (bl,dx) OUT () MOD (ax,bl,dx)
Output:
mov ah, 09h ; DOS.PrintString
int 21h
test bl, bl
pushf ; (1) Need the test result later on
jns IsPositive1
mov dl, '-'
mov ah, 02h ; DOS.PrintChar
int 21h
neg bl
IsPositive1:
lea dx, [bx + '0'] ; BH and DH are not important here
mov ah, 02h ; DOS.PrintChar
int 21h
mov dx, OFFSET PositiveMsg
popf ; (1) Original BL no more available
jns IsPositive2
mov dx, OFFSET NegativeMsg
IsPositive2:
mov ah, 09h
int 21h
ret
If ever you need to go further than a single-digit input/output, then next Q/A's go much deeper into the subject: Inputting multi-radix multi-digit signed numbers with DOS and Displaying numbers with DOS.
Upvotes: 1