0

在从二进制转换为十进制和十六进制值时,此代码有一些错误。该程序向用户显示此菜单:

按您要采取的行动对应的数字:

  1. 如果您想将十进制转换为二进制和十六进制。
  2. 如果您想将二进制数转换为十进制和十六进制。
  3. 如果您想将十六进制数转换为十进制和二进制。
  4. 如果您想退出应用程序。

该程序运行,除了选择 2。波纹管我想出什么,任何想法都会受到赞赏。

INCLUDE irvine32.inc

.data
num DWORD 5
binCounter DWORD ?
binVal BYTE 32 DUP(0)
temp BYTE 0
prompt BYTE "Welcome to the Binary/Decimal/Hex Converter", 0
invalid BYTE "Invalid value, please try again", 0
hexPrompt BYTE "Enter the hexadecial number and press enter key: ",0
DecPrompt BYTE "Enter the decimal number and press enter key: ",0
binPrompt BYTE "Enter the binary number and press enter key: ",0
numInHex BYTE "The number in hexadecimal format: ",0
numInDec BYTE "The number in decimal format: ",0
numInBin BYTE "The number in binary format: ",0
msg_InvalidInputs BYTE "Invalid binary value! Number in binary formate include only 0,1",0
msg_TooManyInputs BYTE "ERROR! The entered binary is more than 32 digit"
menu BYTE "Press number corresponding to the ation you would like to take.",0DH,0AH
    BYTE "1. If you would like to convert a decimal to binary and hexadecimal.",0DH,0AH
    BYTE "2. If you would like to convert a binary nuber to decimal and hexadecimal.",0DH,0AH
    BYTE "3. If you would like to convert a hexadecimal number to decimal and binary.",0DH,0AH
    BYTE "4. If you would like to quit the application.",0DH,0AH

.code
main PROC

    mov edx, OFFSET prompt
    call WriteString
another:
    call Crlf
    mov edx,OFFSET menu
    call WriteString
    call ReadDec
    cmp eax,4
    je stop
    cmp eax,3
    je fromHex
    cmp eax,2
    je fromBin
    cmp eax,1
    je fromDec
    mov edx,OFFSET invalid
    call WriteString
    ;call Crlf
    jmp another

fromHex:
    mov edx,OFFSET hexPrompt
    call WriteString
    call ReadHex
    call print_dec
    call print_bin
    jmp another

fromDec:
    mov edx,OFFSET decPrompt
    call WriteString
    call ReadDec
    call print_hex
    call print_bin
    jmp another

fromBin:
    mov edx,OFFSET binPrompt
    call WriteString
    call ReadBin        ;**Problem root is here**
    call print_dec
    call print_hex
    jmp another

stop:
    call Crlf
    exit
 main ENDP


;-----------------------------------------------
ReadBin PROC
;
;  THE PROBLEM IS IN THIS PROCEDURE
;-----------------------------------------------
        
        push eax
    push ebx
    push ecx
    push edx

    ; get input string
    mov edx, offset binVal
    mov ecx, sizeof binVal

    call ReadString
    cmp eax, 0 ; check zero input
    jz  ZeroInput
    cmp eax, 32 ; at max 32 input characters. 32 characters for 32 bits
    jg  TooManyInputs


    ; validate input string
    mov ebx, eax ; save input string length
    xor ecx, ecx ; set counter to zero
Validate:
    mov al, binVal[ecx] ; move character at ecx to eax
    sub eax, 30h ; subtract character '0' from input to get digit value
    cmp eax, 0 ; compare value with zero
    jl  InvalidInputs ; if less than zero signal error
    cmp eax, 1 ; compare value with one
    jg  InvalidInputs ; if greater than one signal error
    inc ecx ; increment ecx by 1
    cmp ebx, ecx ; compare length
    jg  Validate

; input string is valid, convert value
    mov dl,32;BYTE PTR ebx ; save string size in cl
    dec dl
    xor cl, cl
    ; cl have index of character inside binVal
    ; dl have index of bit inside eax

Convert:
    mov ebx, binVal[cl] ; move character at cl to ebx
    sub ebx, 30h ; subtract character '0' from input to get digit value
    shl ebx, cl  ; shift 0 or 1 by dl bits
    or  eax, ebx ; or ebx with eax
    dec dl ; get location of next bit
    inc cl ; get location of next character
    cmp dl, 0
    jnz Convert

    ; last character
    mov ebx, binVal[cl] ; move character at index 0 to ebx
    sub ebx, 30h ; subtract character '0' from input to get digit value
    or  eax, ebx
    jmp ProcEnd

ZeroInput:
    xor eax, eax
    jmp ProcEnd

TooManyInputs:
    mov edx,OFFSET msg_TooManyInputs
    call WriteString
    xor eax, eax
    jmp ProcEnd

InvalidInputs:
    mov edx,OFFSET msg_InvalidInputs
    call WriteString
    xor eax, eax

ProcEnd:
    pop edx
    pop ecx
    pop ebx
    pop eax
    ret
    ReadBin ENDP    

 ;-----------------------------------------------
print_hex PROC
;
;-----------------------------------------------
     mov      edx,OFFSET numInHex
     call  WriteString
     call WriteHex
     call Crlf
    
     ret
print_hex ENDP


;-----------------------------------------------
print_dec PROC
;
;-----------------------------------------------
     mov      edx,OFFSET numInDec
     call  WriteString
     call WriteDec
     call Crlf 
     ret
print_dec ENDP

;-----------------------------------------------
print_bin PROC
;
;-----------------------------------------------
     mov      edx,OFFSET numInBin
     call  WriteString
     call WriteBin
     call Crlf
     
     ret
print_bin ENDP

END main
4

1 回答 1

0

以下是一些立即突出的事情:

  • menu字符串不是以 NULL 结尾的。

  • 和循环可以合并为一个ValidateConvert我不明白为什么您需要两次遍历字符串。

  • 在您的Convert循环中,您从左到右读取字符串,即从索引 0 开始(因为您CL用作索引)。然后将CL:th数字CL位向左移动(换句话说,您使最右边的位成为最重要的位)。因此,如果您得到字符串"110",您最终会得到1<<0 | 1<<1 | 0<<2== 3,而不是 6 ,这将是正确的答案。

  • 您将循环的循环计数器 ( DL) 设置为Convert32,即使您的字符串可能没有 32 位数字。为什么不设置为BL(即字符串长度的LSB)?

  • 您不清楚and循环EAX之间。这个错误的效果是该部分是不必要的,因为在进入循环时将包含值 0 或 1 ,基于输入字符串中最右边的数字。ValidateConvert; last characterEAXConvert

于 2013-05-12T09:43:13.287 回答