将用户选择的基数转换为基数10 - MASM

时间:2015-06-14 14:45:38

标签: assembly decimal masm base irvine32

程序的目的是让用户选择一个底座(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

0 个答案:

没有答案