程序的目的是让用户选择一个底座(2-16),然后为该底座输入一个或多个数字,然后在2,8,10和16号底座中显示它们。其中一个要求是当我们在用户选择的基础下获得数字选择时,我们将保持运行总计并得出小数值。我认为这个程序的问题在于那个部分。在我的计划中,它将是" Number"和"计算"在功能" ReadInteger"。我确定我还有其他问题,但我需要先解决这个问题才能继续调试我的程序。我已经在这工作了很长时间,并且不确定我做错了什么。似乎EAX寄存器没有正确清除,但我认为我已经控制了它?如果有用户输入,请欣赏有关如何在Visual Studio for MASM中更轻松地调试的一些指示甚至提示。
到目前为止,这是我的代码:
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