i dont know what happn it always says "invalid input!" but my codes are right. here is my code.

.please help me. coz im just new to ths language. tnx
Posted on 2009-10-10 08:49:33 by xxxlancedxxx
Hey LanceD,

Welcome to the forum. First I would like to say that if you are going to post code you'll get more responses if you either post it inline using the [CODE][/CODE] or uploaded as an attachment. If you simply must use an offsite post, try using a source post repository like http://www.sourcepod.com/ which allows you to post an example online for a period of time.

Now, for your code.

	XOR BX, BX		; clear BX



CMP time_out, 2 ; is the first digit of the input greater than 2?

JG HANDLE_ERROR2 ; if yes, ERROR!

JE CHECK_NEXTD2 ; if it is equal to 2, check the second digit

JL CHECK_UNDERTIME2 ; if less than, check undertime.



CHECK_NEXTD2:

INC BX ; increment BX

CMP time_out, 4 ; if the second digit greater than 4?

JG HANDLE_ERROR2 ; if yes, handle error

JMP CHECK_UNDERTIME2 ; if no error, check for possible undertime (when employee goes home before 17:00)



;handling errors

HANDLE_ERROR2:

lea dx, ERROR ;load effect data

mov ah, 9 ;displays data input

int 21h ; execute

JMP EXIT ; jump to exit


This is where your program has problems. When you read in your values, they are in the form of character codes, here you test if the first value read is above 2, if so an error occurs. But since you are dealing with character codes the value entered is always going to be above 2. Same goes for the test against the second value being above 4, although this is not reached. what you need to do is convert these values or test them against the character codes themselves, eg Cmp time_out, '2' and Cmp time_out, '4'. Same goes for the time_in checks. Another error is in your CHECK_UNDERTIME code, you Pop Bx however looking through the code which gets executed before hand I don't see a single Push instruction which leads me to believe this code will also error (however your "Invalid Input!" error occurs before you get to this point.

As an optimization note, you don't need to use BX in your read loop to index the array, since CX constantly the same value as BX you can just use it and save the register and a few instructions:

;input time-in

MOV AH, 1 ; read character function

XOR CX, CX ; clear CX



INPUT:

INT 21H ; execute

MOV time_in, AL ; move contents of AL to array

INC CX ; increment CX by 1

CMP CX, 2 ; is CX = 2?

JE NEXT ; if yes, go to NEXT

JMP INPUT ; if not, loop until all digits are placed in array



NEXT:



;go to new line

MOV AH, 2 ;display char function

MOV DL, 0DH ;carriage return

INT 21H ;execute



MOV DL, 0AH ;line feed

INT 21H ;execute



;display second message (for time out)

lea dx, msg_out ;load effect data

mov ah, 9 ;displays data input

int 21h



;input time-out

MOV AH, 1 ; read character function

XOR CX, CX ; clear CX



OUTPUT:

INT 21H ; execute

MOV time_out, AL ; move contents of AL to array

INC CX ; increment CX

CMP CX, 2 ; is CX = 2?

JE NEXT2 ; if yes, go to NEXT2

JMP OUTPUT ; if not, loop until all digits are placed in array



NEXT2:

;go to new line

MOV AH, 2 ;display char function

MOV DL, 0DH ;carriage return

INT 21H ;execute



MOV DL, 0AH ;line feed

INT 21H ;execute


I just glanced over the code because I have no way of building it at the moment, so I'll leave more detailed analysis to others.
Posted on 2009-10-10 10:43:12 by Synfire
..tnx so much for the help..

..but thre stll an error in the code...

;PROJECT SUMMARY:  user inputs time-in and time-out (by hour).  the usual time-in is 8AM and the time-out is 5PM.
;Base Salary is Php270.00
;A deduction of Php30.00 from the base salary will be done for every hour late
;An additional Php50.00 is given for every hour overtime (until 10PM only)
;Output the daily salary and the monthly salary (daily salary * 30)

TITLE wcalcu.asm WAGE CALCULATOR
.MODEL SMALL
.STACK 100H
.DATA
NOTE db 'DO take note a 24-hour format is followed.  $'
EXAMPLE db 'Ex: 08 corresponds to 8AM while 13 is 1pm.$'
MSG_IN db 'Enter time-in: $'
MSG_OUT db 'Enter time-out: $'
MSG_MIN db 'Enter minimum wage in your company.$'
DAILY_SAL db 'Your daily salary is $'
MONTHLY_SAL db 'Your monthly salary is $'
ERROR1 db 'Invalid Input (time-in!) $'
ERROR db 'Invalid Input (time-out!) $'
daily_wage db ?
monthly_wage db ?
time_in db ?
time_out db ?

.CODE
main proc
;initialize ds
mov ax, @data
mov ds, ax ;initialize data segment

;**************************************************************************;
;---------------------------  OPENING MSGS  -------------------------------;
;**************************************************************************;

;display NOTE
lea dx, NOTE ;load effect data
mov ah, 9 ;displays data input
int 21h

;go to new line
MOV AH, 2 ;display char function
MOV DL, 0DH ;carriage return
INT 21H ;execute

MOV DL, 0AH ;line feed
INT 21H ;execute
;execute

;display example
lea dx, EXAMPLE ;load effect data
mov ah, 9 ;displays data input
int 21h

;go to new line
MOV AH, 2 ;display char function
MOV DL, 0DH ;carriage return
INT 21H ;execute

MOV DL, 0AH ;line feed
INT 21H ;execute

;display msg1 (asking for time-in)
lea dx, msg_in ;load effect data
mov ah, 9 ;displays data input
int 21h

;**************************************************************************;
;------------------------- INPUT and STORING  -----------------------------;
;**************************************************************************;

;input and storing time-in
MOV ah, 1 ; read character function
XOR BX, BX ; clear BX
MOV CX, 0 ; CX = 0

INPUT:
INT 21H ; execute
MOV time_in, AL ; move contents of AL to BL
INC CX ; increment CX by 1
INC BX ; increase BX
CMP CX, 2 ; is CX = 2?
JE NEXT ; if yes, go to NEXT
JMP INPUT ; if not, loop until all digits are placed in array

NEXT:

;go to new line
MOV AH, 2 ;display char function
MOV DL, 0DH ;carriage return
INT 21H ;execute

MOV DL, 0AH ;line feed
INT 21H ;execute

;display second message (for time out)
lea dx, msg_out ;load effect data
mov ah, 9 ;displays data input
int 21h

;input and storing time-out
MOV ah, 1 ; read character function
XOR BX, BX ; clear BX
MOV CX, 0 ; CX = 0

OUTPUT:
INT 21H ; execute
MOV time_out, AL ; move contents of AL to BL
INC CX ; increment CX
INC BX ; increase BX
CMP CX, 2 ; is CX = 2?
JE NEXT2 ; if yes, go to NEXT2
JMP OUTPUT ; if not, loop until all digits are placed in array

NEXT2:
;go to new line
MOV AH, 2 ;display char function
MOV DL, 0DH ;carriage return
INT 21H ;execute

MOV DL, 0AH ;line feed
INT 21H ;execute

;display third message (for minimum wage)
lea dx, msg_min ;load effect data
mov ah, 9 ;displays data input
int 21h

;input and storing min wage
MOV ah, 1 ; read character function
XOR BX, BX ; clear BX
MOV CX, 0 ; CX = 0

WAGE:
INT 21H ; execute
MOV daily_wage, AL ; move contents of AL to BL
INC CX ; increment CX
INC BX ; increase BX
CMP CX, 3 ; is CX = 3?
JE NEXT3 ; if yes, go to NEXT3
JMP WAGE ; if not, loop until all digits are placed in array

NEXT3:
;go to new line
MOV AH, 2 ;display char function
MOV DL, 0DH ;carriage return
INT 21H ;execute

MOV DL, 0AH ;line feed
INT 21H ;execute




;**************************************************************************;
;---------------- CHECKING FOR VALIDITY OF INPUT (TIME-IN)-----------------;
;**************************************************************************;

;checking for validity by comparing each digit in the array:

INPUT1_VALIDITY:
XOR BX, BX ; clear BX

MOV AL, time_in ; move contents of time_in to AL
CMP AL, 31H ; is the first digit of the input less than or equal to 1?
JG HANDLE_ERROR ; if not, ERROR!
JL CHECK_UNDERTIME ; if less than, check undertime.
JE CHECK_NEXTD ; if first digit = 1, check 2nd digit

CHECK_NEXTD:
INC BX ; increment BX
MOV AL, time_in ; move the contents of time_in to AL
CMP AL, 37H ; is the second digit greater than 7?
JG HANDLE_ERROR ; if yes, handle error
JMP CHECK_UNDERTIME ; if no error in input1, check undertime due to tardiness

;handling errors
HANDLE_ERROR:
lea dx, ERROR1 ;load effect data
mov ah, 9 ;displays data input
int 21h
JMP EXIT ; jump to exit!



;**************************************************************************;
;----------------- CHECKING IF UNDERTIME DUE TO TARDINESS -----------------;
;**************************************************************************;

; check if employee is late
CHECK_UNDERTIME:
XOR AX, AX ; clear AX
XOR BX, BX ; clear BX

MOV AL,time_in ; move to AL
CMP AL, 31H ; is the first digit = 1?
JE GET_NEXTD ; if yes, compute the number of hours late
INC BX ; if no, incerement BX
MOV AL, time_in ; move contents to AL
CMP AL, 37H ; if the first digit is not 1, is the next digit greater than 7?
JG COMPUTE_LATE ; if yes, compute the number of hours late
JMP INPUT2_VALIDITY ; if not, check if employee had an overtime

; if time in is 1*
GET_NEXTD:
INC BX ; increment BX
MOV AL, time_in ; AL = time_in
CMP AL, 38h ; is the second digit greater than 8?
JG BORROW ; if yes, go to function borrow (subtraction through borrowing)
JLE COMPUTE_LATE ; if not, subtract the simple way

; subtracting the simple way (no borrwing)
COMPUTE_LATE:
MOV AL, time_in ; AX = time_in[1]
SUB AL, 8h ; AX = AX - 8
JMP UNDERTIME ; subtract salary per hour late

; subtracting through borrowing
BORROW:
MOV AL, 9h ; AX = 9
ADD AL, 1h ; AX = 10
MOV DL, time_in ; DL = time_in
ADD AL, DL ; AX = AX + DL
SUB AL, 8h ; AX = AX - 8
JMP UNDERTIME ; subtract salary per time late

; deducting per hour LATE
UNDERTIME:
MOV BX, 2h ; BX = 2

MOV AL, daily_wage ; move to AL
SUB AL, 3h ; subtract the digit 3 from the 2nd digit of the wage
MOV daily_wage, AL ; copy to BX
CMP AL, 33H ; is the digit less than 3?
DEC BX ; BX = 0
JL BORROW2 ; if yes, borrow from the 1st digit

BORROW2:
MOV AL, daily_wage ; move to AL
DEC AL ; subtract 1 from AL
MOV daily_wage, AL ; copy to array

JMP INPUT2_VALIDITY ; check validity of input 2


;**************************************************************************;
;---------------- CHECKING FOR VALIDITY OF INPUT (TIME-OUT)----------------;
;**************************************************************************;

;checking for validity by comparing each digit in the array:
INPUT2_VALIDITY:
XOR BX, BX ; clear BX

MOV AL, time_out ; move the contents of time_out to AL
CMP AL, 32H ; is the first digit of the input equal to 2?
JE CHECK_IF1 ; if equal to 2, check if the next digit is <= 3
JG HANDLE_ERROR2 ; if greater than, handle error
JMP PRINT
;JL CHECK_OVERTIME ; if it starts with 1, check if employee has OT

CHECK_IF1:
INC BX ; increase BX by 1
MOV AL, time_out ; move the contents to AL
CMP AL, 33H ; check if 2nd digit is less than or equal to 4
JG HANDLE_ERROR2 ; cut off time is 23:00
JMP PRINT
;JMP COMPUTE_OT ; compute no. of hours overtime

;handling errors
HANDLE_ERROR2:
lea dx, ERROR ; load effect data
mov ah, 9 ; displays data input
int 21h ; execute
JMP EXIT ; jump to exit!


;**************************************************************************;
;------------------------PROCESSING OVERTIME ------------------------------;
;**************************************************************************;
;check for overtime

;**************************************************************************;
;------------------------ENDING THE PROGRAM  ------------------------------;
;**************************************************************************;
PRINT:
;print output
;display daily salary
ADD_30H:
MOV AL, daily_wage ; move to AL
ADD AL, 30H ; add 30H to each character
INC BX ; increment BX
CMP BX, 33H ; is BX = 3?
JE display_char ; if equal, display character
JMP ADD_30H ; if not, loop

display_char:
;MOV DL, BL ; retrieve character
INT 21H
;LEA DX,daily_wage
MOV AH,2
INT 21h
; display character
;MOV DL, BL ; retrieve character
;INT 21H


;go to new line
MOV AH, 2 ;display char function
MOV DL, 0DH ;carriage return
INT 21H ;execute

MOV DL, 0AH ;line feed
INT 21H ;execute

EXIT:
;return to DOS
EXIT:
mov ah,4ch ;DOS exit function
int 21h ;execute
main endp
end main


..hope you could help me figure ths out..

..tnx agen..
Posted on 2009-10-11 06:41:48 by xxxlancedxxx
Maybe you should team up lloydie and figure this out for your class, together :idea:
Posted on 2009-10-11 12:44:42 by SpooK
Heh. Yes...

But SpooK, you've been doing 32-bit code too long! "mov in_time, al" isn't going to be a valid effective address in 16-bit code... (aren't you glad you've forgotten that? :)

But Lance could use bx for both index and counter... (just an optimization - it'll work the way you've got it... pretty much...)

After displaying your prompts, you get a character with int 21h/1. Remember that this is a character, not the number it represents(!). You put it in "in_time". Then you loop back for another number and put it in the next byte in the buffer... but you only allocated one byte for the buffer! A buffer overflow, in your very first program!!! :) Seriously, this is a real problem! Always think about what you're letting the pesky user put in your buffer! While we're at it, what are you going to do if the user enters "x", or something else that's not a number? This is the time to catch it!!!

A little later (okay, a lot) you do...

;print output
;display daily salary
ADD_30H:
MOV AL, daily_wage ; move to AL
ADD AL, 30H ; add 30H to each character
INC BX ; increment BX
CMP BX, 33H ; is BX = 3?
JE display_char ; if equal, display character
JMP ADD_30H ; if not, loop

Here, you keep incrementing bx until it's 33h before printing anything. This is going to be way beyond the end of your buffer. This error makes me suspect that you don't "get" the difference between a number, and the character(s) representing the number. You get a character from the keyboard. If it's between '0' (ascii code 30h) and '9' (ascii code 39h), you can simply subtract 30h (you can write this as '0' - "sub al, '0'" may be clearer than "sub al, 30h"... tells us that 30h isn't the number of cars in the parking lot :) If it takes more than one character to represent the number... more complication! If the user types "12", we get '1', subtract '0' and add it to the "result so far" (zeroed, to start), then IFF we get another character, '2'... subtract '0', we multiply the "result so far" by ten and add the new number. We're done, in this case, but we could keep going like that until the user hits "enter"... Now you've got a number you can do arithmetic on - "hours * wage", for example.

When it comes time to print the results of your calculation, you'll need to convert the number back to a character - probably more than one! Add '0' (30h) to each digit to convert it to a character - the "div" instruction will help you isolate digits. Look it up - there are some "strange" features... If you're going to use int 21h/9 to print it, remember that it does a $-terminated string!

Apparently, "youse guys" haven't gotten to "call" and "ret" yet. Pity, this assignment just begs for 'em! Your "newline" routine would make a nice subroutine, as well as the "convert text to number" and "convert number to text" routines - but you can do it repeatedly "inline" as you do with the "newline" if you have to. If it's "allowed", this might be a good time to learn 'em! (See what Homer says in his sig? "Build Bricks". That's the way to think about this!)

Might also be a good time to learn to use a debugger. If you could step through your code instruction by instruction, you'd probably find the errors (if any :) yourself. If not, try to "think like a CPU". See if you can narrow the problem(s) down to more specific question(s) that we can help you with...

Best,
Frank

Posted on 2009-10-12 15:19:59 by fbkotler
...tnx so much guys..

..my prog is now running completely..

...tnx for your help...

..god bless to all of you..
Posted on 2009-10-15 20:28:03 by xxxlancedxxx
god had nothing to do with it, but thanks anyway :)
Posted on 2009-10-16 08:03:44 by Homer