hi everyone!
i need help on may code it is a calculator that asked the user to input an expression (eg. 56+2) in one line and output the answer..it suppose to manipulate mdas.

please help me fix this code..
(i mean this is not really my code but i did tried to fix it.)

.model small
.stack 64
.data
error_alpha db "Invalid input. Expression contains letter/s. ",13,10,"$"
error_range db "Invalid input. Operand/s may be out of range. ",13,10,"$"
error_overflow db "An overflow has occurred. ",13,10,"$"
error_invalidinput db "Invalid Input. ",13,10, "$"
redo db "Please enter a valid one.",13,10,"$"
newline db 13,10,"$"
inputlen dw 2
op1len dw 1
op2len dw 2
prompt db "Enter an expression: ","$"
inputLabel label byte
inputmaxLen db 50
inputcurLen db ?
inputData db 50 dup (?)
str_operand1 db 10 dup (?)
str_operand2 db 10 dup (?)
str_operator db 2 dup (?)

operand_sign1 db 2 dup (?)
operand_sign2 db 2 dup (?)

sign_counter db 0h
multbyTen db 10
op_temp1 dw ?
op_temp2 dw ?

op_fin1 dw ?
op_fin2 dw ?
tempAnswer dw ?
finalAnswer dw ?
divAnswer dw 0h
remainder db ?
finalRem dw ?
outputDecimal db "DECIMAL: $"
outputBinary db "BINARY: $"
outputOctal db "OCTAL: $"
outputHex db "HEXADECIMAL: $"

rev_ascii_decimal db ?
rev_ascii_binary db ?
rev_ascii_octal db ?
rev_ascii_hexadecimal db ?
outputSign db ?

dec_len dw 0h
bin_len dw 0h
oct_len dw 0h
hex_len dw 0h


find_operand1 dw 0h
find_operand2 dw 0h

temp dw 0h

sum dw 0h
multiplier dw 0h
product dw 0h

.code
;asks the user for input
prompt_for_input proc
mov dx, offset prompt
mov ah, 9h
int 21h
mov dx, offset inputLabel
mov ah, 0ah
int 21h
mov bx, 0h
mov bl, inputcurLen
mov inputData, "$"
mov bx, 0
mov bl, inputcurLen
mov inputlen, bx
ret
prompt_for_input endp

; gets the operands and the operator from the one line of input
get_operators_and_operands proc
mov ax, 0
mov bx, 0
mov dx, 0
mov cx, 0
mov si, 0
mov bp, 0
mov op1len, 0h
mov op2len, 0h

pre_conv1:
mov al, inputData
call check_if_digit
jz pre_start_operand1

check_sign1:
cmp al, "-"
je negative_op1
cmp al, "+"
je positive_op1

call invalid_input

negative_op1:
mov operand_sign1[0], "-"
mov operand_sign1[1], "$"
inc bx
jmp start_operand1

positive_op1:
mov operand_sign1[0], "+"
mov operand_sign1[1], "$"
inc bx
jmp start_operand1

pre_start_operand1:
mov operand_sign1[0], "+"
mov operand_sign1[1], "$"
jmp start_operand1

start_operand1:
mov al, inputData
cmp al, " "
je end_operand1
push bx
mov bx, 0
mov bx, cx
mov str_operand1,al
pop bx
inc op1len
inc cx
inc bx
jmp start_operand1

end_operand1:
push bx
mov bx, 0
mov bx, cx
mov str_operand1, "$"
pop bx
jmp get_operator

get_operator:
inc bx
mov al, inputData
mov str_operator[0], al
mov str_operator[1], "$"
inc bx
inc bx
mov ax, 0
mov cx, 0
jmp pre_conv2

pre_conv2:
mov al, inputData
call check_if_digit
jz pre_start_operand2
jnz check_sign2

check_sign2:
cmp al, "-"
je negative_op2
cmp al, "+"
je positive_op2

call invalid_input

pre_start_operand2:
mov operand_sign2[0], "+"
mov operand_sign2[1], "$"
jmp start_operand2

start_operand2:
mov al, inputData
cmp al, "$"
je end_operand2
push bx
mov bx, 0
mov bx, cx
mov str_operand2,al
pop bx
inc op2len
inc cx
inc bx
jmp start_operand2

end_operand2:
push bx
mov bx, 0
mov bx, cx
mov str_operand2, "$"
pop bx

ret

negative_op2:
mov operand_sign2[0], "-"
mov operand_sign2[1], "$"
inc bx
jmp start_operand2

positive_op2:
mov operand_sign2[0], "+"
mov operand_sign2[1], "$"
inc bx
jmp start_operand2
get_operators_and_operands endp

;checks what operator was used and performs the indicated operation
check_operator proc
mov bx, 0
mov bl, str_operator[0]
cmp bl, "+"
jne check_sub
call add_nos
ret
check_sub:
cmp bl, "-"
jne check_mul
call sub_nos
ret
check_mul:
cmp bl, "*"
jne check_div
call mul_nos
ret
check_div:
cmp bl, "/"
jne call_invalid_input
call div_nos
ret
call_invalid_input:
call invalid_input
check_operator endp

;jumps to the procedure input_out_of_range
to_input_out_of_range proc
jmp input_out_of_range
to_input_out_of_range endp

;converts the operands to decimal to be used in the arithmetic operations
convert_operands_to_decimal proc
mov bx, 0h
find_eostring1:
mov ax, 0
mov al, str_operand1
cmp al, "$"
je two
sub al, 30h
mov str_operand1, al
inc bx
jmp find_eostring1
two:
mov bx, 0h
find_eostring2:
mov ax, 0
mov al, str_operand2
cmp al, "$"
je exit_cotd
sub al, 30h
mov str_operand2, al
inc bx
jmp find_eostring2

exit_cotd:
cmp op1len, 6
jg to_input_out_of_range2
cmp op2len, 6
jg to_input_out_of_range2

ret
convert_operands_to_decimal endp

;performs addition if the operator is the '+' sign
add_nos proc
mov cl, operand_sign1[0]
mov bl, operand_sign2[0]
cmp cl, bl
jne subit
mov al, str_operand1
mov dl, str_operand2
add al, dl
add al, 30h
mov dl, al
mov ah, 9h
int 21h
ret
subit:
mov bx, op1len
mov cx, op2len
cmp bx, cx
jl subop2
subop1:
mov cl, operand_sign1[0]
mov outputSign[0],cl
mov outputSign[1],"$"
sub al, dl
ret
subop2:
mov dl, operand_sign2[0]
mov outputSign[0],dl
mov outputSign[1],"$"
sub dl, al
ret
add_nos endp

;performs subtraction if the operator is the '-' sign
sub_nos proc
ret
sub_nos endp

;jumps to the procedure input_out_of_range
to_input_out_of_range2 proc
jmp input_out_of_range
to_input_out_of_range2 endp

;performs multiplication if the operator is the '*' sign
mul_nos proc
mov al, str_operand1
mov dl, str_operand2
mul dl
mov finalAnswer,ax

mov cl, operand_sign1[0]
mov bl, operand_sign2[0]
cmp cl, bl
je outputSign_is_pos
mov outputSign[0],"-"
jmp endsignmul
outputSign_is_pos:
mov outputSign[0]," "
endsignmul:
mov outputSign[1],"$"
ret
mul_nos endp

;performs division if the operator is the '/' sign
div_nos proc
mov dx, 0
mov al, str_operand1
mov bl, str_operand2
div bl
mov remainder, ah
mov ah, 0
mov divAnswer, ax

mov cl, operand_sign1[0]
mov bl, operand_sign2[0]
cmp cl, bl
je outputSign_is_pos2
mov outputSign[0],"-"
jmp endsigndiv
outputSign_is_pos2:
mov outputSign[0]," "
endsigndiv:
mov outputSign[1],"$"
ret
div_nos endp

;prints the error message indicating that an operand's value is greater that 65536
input_out_of_range proc
call print_new_line
mov dx, offset error_range
mov ah, 09h
int 21h
call print_new_line
mov dx, offset redo
mov ah, 09h
int 21h
call print_new_line
jmp start_program
input_out_of_range endp

;prints the error message indicating that an overflow has occured
overflow proc
call print_new_line
mov dx, offset error_overflow
mov ah, 09h
int 21h
call print_new_line
mov dx, offset redo
mov ah, 09h
int 21h
call print_new_line
jmp start_program
overflow endp

;checks if there is a letter in the input
isalpha proc
mov cx , inputlen
mov si, 0
start:
mov ax, 0
mov al, inputData
call check_if_alpha
jz input_is_alpha
inc si
loop start
ret
isalpha endp

;prints the error message indicating that there are letter/s or symbol/s in the input
input_is_alpha proc
call print_new_line
mov dx, offset error_alpha
mov ah, 09h
int 21h
call print_new_line
mov dx, offset redo
mov ah, 09h
int 21h
call print_new_line
call start_program
input_is_alpha endp

;prints the error message indicating that the syntax of the input is wrong
invalid_input proc
call print_new_line
mov dx, offset error_invalidinput
mov ah, 09h
int 21h
call print_new_line
mov dx, offset redo
mov ah, 09h
int 21h
call print_new_line
call start_program
;ret
invalid_input endp

;prints the decimal equivalent of the answer
print_decimal_output proc
mov dx, offset outputDecimal
mov ah, 9h
int 21h

mov ax, finalAnswer
mov bl, 0ah
div bl
mov ah, 0
mov rev_ascii_decimal,al

mov bx, 0
mov cx, dec_len
convertdecloop:
mov al, rev_ascii_decimal
add al, 30h
mov rev_ascii_decimal, al
inc bx
loop convertdecloop

mov ax, 0
mov bx, 0
mov cx, dec_len
;mov bx, dec_len
decimalloop:
mov ah, 02h
mov dl, rev_ascii_decimal
int 21h
inc bx
loop decimalloop

call print_new_line
call print_binary_output
print_decimal_output endp

;prints the binary equivalent of the number
print_binary_output proc
mov dx, offset outputBinary
mov ah, 9h
int 21h

mov dx, offset outputSign
mov ah, 02h
int 21h

mov bx, 0
mov ax, finalAnswer
convertbinloop:
mov cl, 2
div cl
cmp ah, 0
je zerobin
mov rev_ascii_binary,"1"
zerobin:
mov rev_ascii_binary,"0"
nextbin:
inc bx
cmp bx, bin_len
je endbinary
jmp convertbinloop

endbinary:
;mov bx, bin_len
;mov bx, 4
mov rev_ascii_binary,"$"
;mov ax, 0
mov bx, 4
;mov cx, bin_len
mov cx, 4
;mov bx, bin_len

binaryloop:
mov ah, 02h
mov dl, rev_ascii_binary
int 21h
dec bx
loop binaryloop

call print_new_line
ret
;call print_octal_output
print_binary_output endp

;prints the octal equivalent of the answer
print_octal_output proc
mov dx, offset outputOctal
mov ah, 9h
int 21h

mov ax, finalAnswer
convertoctloop:
mov cl, 16
div cl
cmp ah, 0
je zerooct
mov rev_ascii_octal, "1"
jmp nextoct
zerooct:
mov rev_ascii_octal, "0"
nextoct:
inc bx
cmp bx, oct_len
je endoct
jmp convertoctloop
endoct:
mov rev_ascii_octal,"$"

mov ax, 0
mov bx, 0
mov cx, oct_len
mov bx, oct_len
octalloop:
mov ah, 02h
mov dl, rev_ascii_octal
int 21h
inc bx
loop octalloop

call print_new_line
call print_hex_output
print_octal_output endp

;prints the hexidecimal equivalent of the number
print_hex_output proc
mov dx, offset outputHex
mov ah, 9h
int 21h
mov ax, finalAnswer
mov bx, 0
converthexloop:
mov cl, 16
div cl
cmp ah, 0
je zerohex
mov rev_ascii_hexadecimal, "1"
jmp nexthex
zerohex:
mov rev_ascii_hexadecimal, "0"
nexthex:
inc bx
cmp bx, hex_len
je endhex
jmp converthexloop
endhex:
mov rev_ascii_hexadecimal,"$"

mov ax, 0
mov cx, hex_len
mov bx, hex_len
hexadecimalloop:
mov ah, 02h
mov dl, rev_ascii_hexadecimal
int 21h
inc bx
loop hexadecimalloop

call end_program
print_hex_output endp

;prints a new line
print_new_line proc
mov dx, offset newline
mov ah, 09h
int 21h
ret
print_new_line endp

check_if_alpha proc
push ax
and al, 11011111b
cmp al, 'A'
jb B1
cmp al, 'Z'
ja B1
test ax, 0
B1: pop ax
ret
check_if_alpha endp

check_if_digit proc
cmp al, '0'
jb A1
cmp al, '9'
ja A1
test ax, 0
A1: ret
check_if_digit endp

;terminates the program
end_program proc
mov ah, 4ch
int 21h
end_program endp

main proc
mov ax, @data
mov ds, ax

call setcolors

start_program:
call prompt_for_input
call print_new_line

mov dx, offset inputData
mov ah, 09h
int 21h

call isalpha

call print_new_line

call get_operators_and_operands

call convert_operands_to_decimal

call check_operator

call print_decimal_output
call end_program

main endp

end main
Posted on 2011-10-07 07:53:43 by 77nevaeh
What's it do? Or not do?

As a general rule, when you're asking for help with code, it's a good idea to mention what OS (obvious, in this case), what assembler (also obvious, I guess), what command line you gave the assembler (and the linker, if applicable), what you "expect" it to do (obvious, I guess), and what happened instead. Narrow it down, so we know where to look...

This looks like "homework". We'll "help" with homework, but we don't want to "cheat" you by allowing you to "not learn assembly language"! Expect "hints", rather than a finished solution...

Best,
Frank

Posted on 2011-10-07 10:11:22 by fbkotler
i doesn't convert the ascii to decimal and when i input 32+1
the output is "32+1 invalid input, please enter a valid one."

we use TASM as the compliler.

the input suppose to be a string (expression) and can do the mdas.
ex..
input: 32+1
output: 33
Posted on 2011-10-07 10:19:14 by 77nevaeh
Something that looks a little "suspicious" to me is your "start_operand1:"... It looks for a space to indicate the end of the first operand. If it doesn't find a space, it keeps going. The first space it finds may be in "DECIMAL: $"... Try entering a space between "32" and "+", and see if that helps... If it does, you might need to prompt "always enter a space...", or you might want to modify "start_operand1" to catch this situation.

I'm not conveniently able to actually test your code at the moment, so I'm trying to read through it and "think like a CPU". No guarantee I'm right, but that's the first thing that "looks funny".

Best,
Frank

Posted on 2011-10-07 12:11:02 by fbkotler