基于MASM与Irvine32库的二进制与十六进制互转实现问题
汇编程序扩展:添加十六进制与二进制、十进制的双向转换功能
我在Visual Studio环境中使用MASM语法及Irvine32库开发汇编程序,目前已实现二进制与十进制的互转功能,但卡在二进制与十六进制的互转实现环节。现希望完善程序,使其支持十六进制与二进制、十进制的双向转换,以下是我的现有代码:
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
解决方案
1. 更新菜单与数据段
首先在.data段添加新的菜单提示字符串和变量:
; 新增菜单选项字符串 str16 BYTE " 4. Binary to Hexadecimal", 0 str17 BYTE " 5. Hexadecimal to Binary", 0 str18 BYTE " 6. Decimal to Hexadecimal", 0 str19 BYTE " 7. Hexadecimal to Decimal", 0 ; 新增输入输出提示字符串 str20 BYTE "The hexadecimal of ", 0 str21 BYTE " is ", 0 str22 BYTE "Please Enter a hexadecimal number (00-FF): ", 0 str23 BYTE "The binary of hex ", 0 str24 BYTE " is ", 0 str25 BYTE "The decimal of hex ", 0 ; 新增变量存储十六进制输入 hexNum BYTE 3 DUP(?)
然后修改主菜单的输出逻辑,添加新选项:
_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 str16 call WriteString call crlf mov edx, offset str17 call WriteString call crlf mov edx, offset str18 call WriteString call crlf mov edx, offset str19 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, 4 ;IF = 4 je _proc4 ;JUMP TO BINARY TO HEX cmp choice, 5 ;IF =5 je _proc5 ;JUMP TO HEX TO BINARY cmp choice, 6 ;IF =6 je _proc6 ;JUMP TO DECIMAL TO HEX cmp choice,7 ;IF=7 je _proc7 ;JUMP TO HEX TO DECIMAL cmp choice, 3 ;IF = 3 je _proc3 ;JUMP TO PROC3
2. 实现二进制转十六进制(_proc4)
复用已有二进制转十进制的逻辑,将二进制数转为十进制后,调用Irvine32的WriteHexB输出十六进制:
_proc4: ;BINARY TO HEXADECIMAL mov edx, offset str7 call WriteString mov edx, offset num1 mov ecx, sizeof num1 call ReadString mov numLength, eax mov eax, 0 mov esi, 0 mov ecx, numLength mov deciNum, 0 ;重置十进制数,避免累加旧结果 whileProc4 : cmp ecx, 0 je printHexResult mov outLoop, ecx ifProc4 : cmp num1[esi], '0' je incEsiProc4 cmp num1[esi], '1' mov ecx, numLength sub ecx, esi dec ecx mov eax, 1 whileProc4_2 : cmp ecx,0 je stopProc4 mov ebx, base mul ebx dec ecx jmp whileProc4_2 stopProc4 : add deciNum, eax incEsiProc4 : inc esi mov ecx, outLoop dec ecx jmp whileProc4 printHexResult : mov edx, offset str8 call WriteString mov edx, offset num1 call WriteString mov edx, offset str20 call WriteString mov eax, deciNum call WriteHexB call crlf call crlf jmp _mainprog
3. 实现十六进制转二进制(_proc5)
调用Irvine32的ReadHex读取十六进制数,再用WriteBinB输出二进制:
_proc5: ;HEXADECIMAL TO BINARY mov edx, offset str22 call WriteString call ReadHex ;读取十六进制数到EAX mov deciNum, eax ;存储数值 mov edx, offset str23 call WriteString mov eax, deciNum call WriteHexB mov edx, offset str24 call WriteString call WriteBinB call crlf call crlf jmp _mainprog
4. 实现十进制转十六进制(_proc6)
读取十进制数后直接调用WriteHexB输出:
_proc6: ;DECIMAL TO HEXADECIMAL mov edx, offset str11 call WriteString call ReadDec ;读取十进制数到EAX mov deciNum, eax mov edx, offset str12 call WriteString mov eax, deciNum call WriteDec mov edx, offset str20 call WriteString call WriteHexB call crlf call crlf jmp _mainprog
5. 实现十六进制转十进制(_proc7)
读取十六进制数后调用WriteDec输出:
_proc7: ;HEXADECIMAL TO DECIMAL mov edx, offset str22 call WriteString call ReadHex ;读取十六进制数到EAX mov deciNum, eax mov edx, offset str25 call WriteString mov eax, deciNum call WriteHexB mov edx, offset str9 call WriteString call WriteDec call crlf call crlf jmp _mainprog
6. 修复原代码小问题
- 原
_proc1中每次转换前添加mov deciNum, 0,避免累加之前的转换结果 - 修正
str8中的拼写错误:将decimel改为decimal
内容的提问来源于stack exchange,提问作者Arciel Shin
相关产品推荐
相关产品推荐

