The point of the program is to let the user choose a base (2-16) and then enter in a number or numbers for that base and then display them in bases 2,8,10 and 16. One of the requirements is that when we are getting the number choices under the user chosen base, we are to keep a running total and come up with the decimal value. I think my problem with this program is at that part. In my program it would be "Number" and "Calculating" under the function "ReadInteger". I'm sure I have other issues, but I need to fix this first to continue debugging my program. I've been working at this for a long time and am not sure what I'm doing wrong. It seems like the EAX register isn't clearing properly, but I thought I had that under control? Would appreciate some pointers or even tips on how to debug easier in Visual Studios for MASM when there's user input.
Here is my code so far:
INCLUDE Irvine32.inc
.data
prompt BYTE 'Enter base value (2 thru 16 or 0 to exit):', 0
prompt1 BYTE 'Enter a number in your chosen base:', 0
error BYTE 'That is not within the accepted range, please try again.', 0
report1 BYTE 'Base 2: ', 0
report2 BYTE 'Base 8: ', 0
report3 BYTE 'Base 10: ', 0
report4 BYTE 'Base 16: ', 0
Temp DWORD ?
Temp1 DWORD ?
BaseNumber BYTE ?
.code
main PROC
; Main program control procedure.
; Calls: WriteString, ReadInteger, AsciiToDigit,
; Crlf, DisplayIntegers
Start:
xor eax,eax ;Clear EAX register
xor ebx,ebx ;Clear EBX register
mov edx,OFFSET prompt ;Prompt user for base choice
call WriteString
mov al,1 ;Set AL to 1 for ReadInteger Function
call ReadInteger ;Get Base choice
cmp al,'0' ;If al is 0 then exit program
je Finish
call AsciiToDigit ;Change character to digit
mov BaseNumber,al ;Save the base choice
call Crlf ;New line
mov edx,OFFSET prompt1 ;Prompt user for number in chosen base
call WriteString
mov al,2 ;Set AL to 2 for ReadInteger Function
call ReadInteger ;Get number in chosen base
cmp al,'0' ;If al is 0 then exit program
je Finish
call Crlf ;New line
call DisplayIntegers ;Display results in base 2,8,10 and 16
call Crlf ;New line
jmp Start ;Restart Program
Finish:
exit ;exit to operating system
main ENDP
;-------------------------------------------------------------
ReadInteger PROC
;
; Takes in user's Base choice and Numbers. Validates both and
; calculates decimal value
; Receives: AL value of 1 or 2
; Returns: Base value in BL and decimal value in Temp1
; Calls: ReadChar,WriteChar,AsciiToDigit,IsLegal,WriteString
;----------------------------------------------------------------
mov esi,0
cmp al, 1 ;If AL is 1 then jump to Base section
je Base
cmp al, 2 ;If AL is 2 then jump to Number section
je Number
Base:
call ReadChar ;Read input
cmp al,'0' ;Jump to invalid if less than 0
jl Invalid
cmp al,'0' ;End program if 0 is entered
je EndFunction
cmp al,'9' ;Jump to invalid if more than 9
jg Invalid
cmp al,'1' ;Jump to One if 1 is entered
je One
call WriteChar ;Display character entered
mov bl,al ;Save base number in BL register
jmp EndFunction ;End the function
One:
call WriteChar ;Display the 1
mov bl,10h ;place it in the 10s column
jmp NextChar
NextChar:
xor eax,eax ;clear eax register
call ReadChar ;Read user character entry
cmp al,'6' ;Jump to invalid if entry is bigger than 6
jg Invalid
call WriteChar ;Display entry
call AsciiToDigit ;Change from Ascii to digit
add bl,al ;Add to the previous 10h in BL register
jmp EndFunction ;End the function
Invalid:
mov edx,OFFSET error ;Display Error message
call WriteString
mov edx,OFFSET prompt ;Display prompt to re-enter
call WriteString
jmp Base
Number:
xor eax,eax ;Clear eax register
call ReadChar ;Read user entry
cmp al,0Dh ;With Enter jump to noneEntered
je NoneEntered
mov bl,BaseNumber ;Get the base number into the bl register
call IsLegal ;Check to see if entry is legal with base choice
cmp al,0 ;if AL is 0 jump back to number
je Number
mov eax, Temp ;Put the number from Temp into EAX register
mov Temp1,eax ;Put the value of EAX into Temp1
Calculating:
call ReadChar ;Read user entry
cmp al,0Dh ;With Enter jump to EndFunction
je EndFunction
call IsLegal ;Check to see if entry is legal with base choice
xor eax,eax ;clear eax register
mov eax, Temp1 ;Put Temp1 value in EAX register
mul ebx ;multiply EAX by EBX register
add eax, Temp ;Add temp value to EAX
mov Temp1, eax ;Place the new EAX value into Temp1
jmp Calculating ;Repeat as long as there is no Enter press
EndFunction:
ret
NoneEntered:
mov al,0 ;AL is 0 if no legal characters are entered
ret
ReadInteger ENDP
;----------------------------------------------------------------
DisplayIntegers PROC
; Displays Number in base 2,8,10,16 using WriteInteger
; Receives: Nothing
; Returns: Value in BL
; Calls: WriteString,WriteInteger,Crlf
;----------------------------------------------------------------
call Crlf ;New line
mov edx,OFFSET report1 ;Display Base 2 value
call WriteString
mov bl,2 ;Set BL to 2 for WriteInteger Function
call WriteInteger
call Crlf ;New line
mov edx,OFFSET report2 ;Display Base 8 value
call WriteString
mov bl,8 ;Set BL to 8 for WriteInteger Function
call WriteInteger
call Crlf ;New line
mov edx,OFFSET report3 ;Display Base 10 value
call WriteString
mov bl,10 ;Set BL to 10 for WriteInteger Function
call WriteInteger
call Crlf ;New line
mov edx,OFFSET report4 ;Display Base 16 value
call WriteString
mov bl,16 ;Set BL to 16 for WriteInteger Function
call WriteInteger
call Crlf ;New line
ret
DisplayIntegers ENDP
;------------------------------------------------------------------
WriteInteger PROC
; Calculates the value in base 2,8,10,16 and displays
; Receives: BL value of 2,8,10 or 16
; Returns: Nothing
; Calls: WriteChar
;---------------------------------------------------------------------
mov eax,Temp1 ;Set EAX register equal to Temp1
mov Temp,eax ;Set Temp equal to EAX value
cmp bl,2 ;If Bl is 2 jump to Convert2
je Convert2
cmp bl,8 ;If Bl is 8 jump to Convert8
je Convert8
cmp bl,10 ;If Bl is 10 jump to Convert10
je Convert10
cmp bl, 16 ;If Bl is 16 jump to Convert16
je Convert16
Convert2:
xor edx,edx ;clear out edx register
xor eax,eax ;clear eax register
mov eax,Temp ;Set eax register equal to Temp
mov ecx,2 ;Divide by ecx - 2
div ecx
mov Temp,eax ;Move new eax value to Temp
mov eax, edx ;move edx (remainder) to eax
add eax,30h ;change to Ascii
call WriteChar ;Display character
mov eax,Temp ;Place Temp value in EAX
cmp eax,2 ;If EAX is less than 2 go to next
jl NextConversion
jmp Convert2 ;Repeat
Convert8:
xor edx,edx ;Clear edx register
xor eax,eax ;Clear eax register
mov eax,Temp ;Divide Temp by 8
mov ecx,8
div ecx
mov Temp,eax ;Store new eax value in Temp
mov eax, edx ;Store edx (remainder in eax)
add eax,30h ;Change to Ascii and display
call WriteChar
mov eax,Temp ;If temp is less than 8 jump to next
cmp eax,8
jl NextConversion
jmp Convert8
Convert10:
mov ecx,SIZEOF Temp ;Get bit size of temp
mov esi,0 ;Set place in string
WriteOut:
xor eax,eax ;Clear eax register
mov eax,Temp[esi] ;set eax to first value in string Temp
add eax,30h ;Display character
call WriteChar
inc esi ;Go to next place in string
Loop WriteOut
jmp NextConversion
Convert16:
xor edx,edx ;clear edx register
xor eax,eax ;clear eax register
mov eax,Temp ;Divide Temp by 16
mov ecx,16
div ecx
mov Temp,eax ;Put new eax value in Temp
mov eax, edx ;set edx (remainder) to eax
cmp eax,9 ;If larger than 9 jump to HexTable
jg HexTable
add eax,30h ;Otherwise display character
call WriteChar
mov eax,Temp ;If Temp is less than 16 go to Next
cmp eax,16
jl NextConversion
jmp Convert16
HexTable:
add eax,37h ;Find correct character for above 9 values
call WriteChar
mov eax,Temp
cmp eax,16
jl NextConversion
jmp Convert16
NextConversion:
ret
WriteInteger ENDP
;-----------------------------------------------------------------
AsciiToDigit PROC
;
; Changes Ascii Character to Digit
; Receives: Ascii Character in the AL register
; Returns: Decimal Value in the AL register
; Calls: None
;------------------------------------------------------------------
cmp al, 60h ;if hexidecimal value is greater than 60h jump to lowercase
jg LowerCase
cmp al, 40h ;if greater than 40h jump to Upper
jg UpperCase
sub al, 30h ;Get digit value
ret
LowerCase: ;get lower case value
sub al,57h
ret
UpperCase: ;get upper case value
sub al,37h
ret
AsciiToDigit ENDP
;-------------------------------------------------------------------
DigitToAscii PROC
; Converts Decimal value to Ascii character
; Receives: Decimal AL register value
; Returns: Ascii character value in AL register
; Calls: None
;-------------------------------------------------------------------
cmp al, 9h ;if larger than 9h is letter
jg Letter
add al, 30h ;change to ascii
ret
Letter: ;change to ascii
add al, 37h
ret
DigitToAscii ENDP
;------------------------------------------------------------------------------
IsLegal PROC
; Validates for legal values under the specific base
; Receives: Base value in BL register and number in AL register to validate
; Returns: AL register value of 0 for not legal and 1 for legal
; Calls: AsciiToDigit,WriteChar,DigitToAscii
;------------------------------------------------------------------------------
call AsciiToDigit ;Change to digit
cmp al,bl ;Compare digit to base value
je NotLegal ;if equal or greater it is not legal
cmp al,bl
jg NotLegal
jmp Legal
NotLegal: ;return 0 in AL to symbolize not legal
mov al,0
ret
Legal: ;Display character and return 1 for legal
mov Temp,eax ;save digit in temp
call DigitToAscii
call WriteChar
mov al,1
ret
IsLegal ENDP
END main