assembly MASM -如何将二进制转换为六进制?

wr98u20j  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(160)

我在Visual Studio上使用的是带有Irvine 32库的MASM语法。
我试图使这个程序转换二进制到十进制,反之亦然,现在我坚持对如何转换二进制到十六进制,反之亦然
这是我的代码

INCLUDE Irvine32.inc


.data
    str1 BYTE ">>> Please select the conversion type: ", 0
    str2 BYTE " 1. Binary to Decimal", 0
    str3 BYTE " 2. Decimal to Binary", 0
    str4 BYTE " 3. Exit", 0 
    str5 BYTE "-----------------------------------------", 0
    str6 BYTE "Enter your choice: ", 0
    str7 BYTE "Please Enter 8-bit binary digits (e.g., 11110000): ", 0
    str8 BYTE "The decimel integer of ", 0
    str9 BYTE " is ", 0
    str10 BYTE " ", 0
    str11 BYTE "Please Enter a decimal integer less than 256: ", 0
    str12 BYTE "The binary of ", 0
    str13 BYTE " is ", 0
    str14 BYTE " ", 0
    str15 BYTE "Bye.", 0
    choice DWORD ?
    num1 BYTE 9 DUP(? )
    num2 WORD ?
    numLength DWORD 0
    outLoop DWORD 0
    base DWORD 2
    deciNum DWORD ?

.code
main PROC
    
    _mainprog :             ;USED TO DISPLAY THE MENU & EXIT
    mov edx, offset str1 
    call WriteString
    call crlf
    mov edx, offset str2
    call WriteString
    call crlf
    mov edx, offset str3
    call WriteString
    call crlf
    mov edx, offset str4
    call WriteString
    call crlf
    mov edx, offset str5
    call WriteString
    call crlf
    mov edx, offset str6
    call WriteString
    call ReadDec            ;DISPLAY OUTPUT
    mov choice, eax         ;EAX = 1
    cmp choice, 1           ;IF = 1
    je _proc1               ;JUMP TO PROC1
    cmp choice, 2           ;IF = 2
    je _proc2               ;JUMP TO PROC2
    cmp choice, 3           ;IF = 3
    je _proc3               ;JUMP TO PROC3

    _proc1 :                ;BINARY TO DECIMAL
    mov edx, offset str7    
    call WriteString
    mov edx, offset num1    ;ASSIGN NUM1 TO EDX TO WRITE THE BINARY IN STRING FORMAT
    mov ecx, sizeof num1    ;ASSIGN TO ECX TO ACT AS THE COUNTER (COUNT THE LENGTH OF THE BINARY DIGIT)
    call ReadString         ;USER INPUT BINARY NUMBER
    mov numLength, eax      ;USER INPUT EAX STORED IN NUMLENGTH
    mov eax, 0              ;EAX ASSIGNED TO 8
    mov esi, 0              ;ESI TO ACCESS THE STRING BINARY INPUT THAT WE ENTERED
    mov ecx, numLength      
    whileProc1 :
    cmp ecx, 0              ;COMPARE COUNTER WITH 0
    je printResult          ;IF ECX =/ 0, IT WILL NOT JUMP TO PRINT RESULT
    mov outLoop, ecx        ;8 ASSIGNED TO OUTLOOP AND ASSIGNED TO REGISTER ECX
    ifProc :                
    cmp num1[esi], '0'      ;IF 1ST VALUE IN THE BINARY DIGIT = 0
    je incEsiProc           ;JUMP TO INCREASE ESI PROC
    elseIfProc:
    cmp num1[esi], '1'      ;IF 1ST VALUE IN BINARY DIGIT = 1
    mov ecx, numLength      ;NUMLENGTH ASSIGNED TO ECX
    sub ecx, esi            ;
    dec ecx
    mov eax, 1
    whileProc2 :
    je stopProc
    mov ebx, base
    mul ebx
    dec ecx
    jmp whileProc2
    stopProc :
    add deciNum, eax
    jmp incEsiProc
    incEsiProc :
    inc esi
    mov ecx, outLoop
    dec ecx
    jmp whileProc1
    printResult :
    mov edx, offset str8
    call WriteString
    mov edx, offset num1
    call WriteString
    mov edx, offset str9
    call WriteString
    mov eax, deciNum
    call WriteDec
    mov edx, offset str10
    call WriteString
    call crlf
    call crlf
    jmp _mainprog

    _proc2:                 ;DECIMAL TO BINARY
    mov edx, offset str11
    call WriteString
    mov edx, offset num2
    call ReadInt
    mov num2, ax
    mov ebx, 1
    mov edx, offset str12
    call WriteString
    mov ax, num2
    call WriteDec
    mov edx, offset str13
    call WriteString
    call WriteBinB
    mov edx, offset str14
    call WriteString
    call crlf
    call crlf
    jmp _mainprog

    _proc3:
    mov edx, offset str15
    call WriteString
    call crlf
    call WaitMsg
    exit
main ENDP
END main

能够要求用户输入一个数字和转换十六进制到二进制/十进制,反之亦然

oewdyzsn

oewdyzsn1#

这就是程序现在的样子,我用这个算法将二进制字符串转换为整数。:)
1.二进制到十进制
1.十进制到二进制
1.二进制到十六进制
1.十六进制到二进制

include \masm32\include\Irvine32.inc
includelib \masm32\lib\Irvine32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

.data
    menu             BYTE "-----------------------------------------",13,10         
                     BYTE "    Please select the conversion type ",13,10 
                     BYTE "-----------------------------------------",13,10
                     BYTE " 1. Binary to Decimal",13,10
                     BYTE " 2. Decimal to Binary",13,10
                     BYTE " 3. Binary to Hex",13,10
                     BYTE " 4. Hex to Binary",13,10
                     BYTE "-----------------------------------------",13,10                     
                     BYTE " 5. Exit",13,10
                     BYTE "-----------------------------------------",13,10
                     BYTE "Enter your choice: ",0
    menu_error       BYTE "*** You entered wrong number. Try again.", 0    
   
    bin_input_msg    BYTE "Please enter 8-bit binary digits (e.g., 11110000): ", 0
    bin_string_error BYTE "*** Cannot convert binary string to integer. Try again.", 0 

    bin_msg_1        BYTE "The binary of ", 0

    dec_input_msg    BYTE "Please enter a decimal integer less than 256: ", 0
    dec_input_error  BYTE "*** Enter value from range 0 - 255.", 0

    dec_msg_1        BYTE "The decimal integer of ", 0    

    hex_input_msg    BYTE "Please enter a hex value: ", 0
  
    hex_msg_1        BYTE "The hex of ", 0

    is               BYTE " is ", 0    
    exit_msg         BYTE "Bye.", 0
    
    binary_string    BYTE 9 DUP(0)
 
    InitFlag         DB 0
    consoleInHandle  DWORD ?        ; handle to console input device
    consoleOutHandle DWORD ? 
;----------------------------------------------------------------------   
    CheckInit MACRO

    ; Helper macro
    ; Check to see if the console handles have been initialized
    ; If not, initialize them now.

   LOCAL exit
      cmp InitFlag,0
      jne exit
      call Initialize
     exit:
   ENDM   
     
;----------------------------------------------------------------------
.code
main PROC

;----------------------------------------------------------------------
;   MENU    
    
    _mainprog: 
        call Clrscr
                
        mov edx, offset menu
        call WriteString        
        call ReadDec            ;eax = user's choice       
        call crlf           
        
        cmp eax, 1           
        je _bin_dec   
        cmp eax, 2           
        je _dec_bin             
        cmp eax, 3           
        je _bin_hex   
        cmp eax, 4           
        je _hex_bin             
        cmp eax, 5           
        je _exit                
        jmp _wrong_number
        
;----------------------------------------------------------------------
;   BINARY TO DECIMAL

    _bin_dec:
        call BinaryString2Int                 
        mov edx, offset dec_msg_1
        call WriteString
        mov edx, offset binary_string 
        call WriteString
        mov edx, offset is
        call WriteString
        call WriteDec
        call _new_line       

        jmp _mainprog

;----------------------------------------------------------------------
;   DECIMAL TO BINARY

    _dec_bin:                 
        mov edx, offset dec_input_msg
        call WriteString
        call ReadDec
        cmp eax,255             ;check if value is 0 - 255 
        ja GreaterThan255
        
        mov edx, offset bin_msg_1
        call WriteString
        call WriteDec
        mov edx, offset is
        call WriteString
        mov ebx, 1             ; 1 - byte, 2 - word, 4 - dbl word
        call WriteBinB
        call _new_line 
              
        jmp _mainprog
        
        GreaterThan255:
            call crlf 
            mov edx, offset dec_input_error
            call WriteString
            call _new_line       
   
            jmp _dec_bin

;----------------------------------------------------------------------
;   BINARY TO HEX

    _bin_hex:                
        call BinaryString2Int  
        mov edx, offset hex_msg_1
        call WriteString
        mov edx, offset binary_string
        call WriteString
        mov edx, offset is
        call WriteString
        call WriteHex
        call _new_line       
        
        jmp _mainprog

;----------------------------------------------------------------------
;   HEX TO BINARY

    _hex_bin:                 
        mov edx, offset hex_input_msg
        call WriteString
        call ReadHex        
        mov edx, offset bin_msg_1
        call WriteString       
        call WriteHex
        mov edx, offset is
        call WriteString
        mov ebx,4              ; 1 - byte, 2 - word, 4 - dbl word
        call WriteBinB
        call _new_line
        
        jmp _mainprog
        
;----------------------------------------------------------------------
;   NUMBER IS NOT ON THE MENU LIST

    _wrong_number:      
        mov edx, offset menu_error
        call WriteString
        call _new_line

        jmp _mainprog

;----------------------------------------------------------------------
;   NEW LINE

    _new_line:
        call crlf
        call crlf
        call WaitMsg            
        call crlf        
        ret
        
;----------------------------------------------------------------------
;   EXIT

    _exit:
        mov edx, offset exit_msg
        call WriteString
        call crlf
        call WaitMsg
        exit
        
main ENDP

BinaryString2Int Proc

;----------------------------------------------------------------------
;   INPUT - BINARY STRING

    _bin_string_input:
        mov edx, offset bin_input_msg    
        call WriteString
        mov edx, offset binary_string    
        mov ecx, sizeof binary_string     
        call ReadString  

;----------------------------------------------------------------------
;   BINARY STRING TO INT
;   Algorithm taken from -> https://stackoverflow.com/a/49548057/20889367

    mov edi, offset binary_string
    movzx   eax, byte ptr [edi]    ; start with the first digit
    sub     eax, '0'               ; convert from ASCII to number
    cmp     al, 1                  ; check that it's a decimal digit [0..1]
    jbe     _loop_entry            ; too low -> wraps to high value, fails unsigned compare check

    xor     eax,eax                ; else: bad first digit: return 0
    jmp conversionError ;ret

    ; rotate the loop so we can put the JCC at the bottom where it belongs
    ; but still check the digit before messing up our total

    _next_digit:                  
        ; lea     eax, [eax*4 + eax]   
        lea     eax, [eax*2 + ecx]    ; total = total*2 + digit
        ; imul eax, 2  / add eax, ecx

    _loop_entry:
        inc     edi
        movzx   ecx, byte ptr[edi]
        sub     ecx, '0'
        cmp     ecx, 1
        jbe     _next_digit  
        ret                            ; return with total in eax 

        conversionError:
            call crlf 
            mov edx, offset bin_string_error
            call WriteString
            call crlf  
            call crlf        
            jmp _bin_string_input
    ret
BinaryString2Int Endp

Initialize PROC private
;----------------------------------------------------------------------
;   Get the standard console handles for input and output,
;   and set a flag indicating that it has been done.
;   Updated 03/17/2003

    pushad

    INVOKE GetStdHandle, STD_INPUT_HANDLE
    mov [consoleInHandle],eax

    INVOKE GetStdHandle, STD_OUTPUT_HANDLE
    mov [consoleOutHandle],eax

    mov InitFlag,1

    popad
    ret
Initialize ENDP
END main

相关问题