自定义汇编语言实现二进制转十进制程序输出结果异常求助
Hey there! I’ve gone through your custom assembly code for binary-to-decimal conversion and spotted several key issues that are likely causing your unexpected results. Let’s break them down one by one, then fix the code together.
1. 跳转标签错误(复制粘贴失误)
In the section handling the least significant bit (the 1's place), you have a JMP wrote4bit instead of JMP wrote1bit. This misjump will send your program back to the wrong section, completely breaking the execution flow after processing the last binary digit.
2. write10first 子程序逻辑完全错误
Your current write10first is meant to handle two-digit decimal values (≥10), but the logic here is broken:
- You subtract 0xA (10) from BX but don’t track how many times you do this (this count should be the tens digit)
- You’re trying to use
[0xA4]which was initialized to 0 and never updated, so you’ll just output '0' twice - The order of operations is reversed—you need to calculate the tens digit first, then the ones digit
3. readtobx 子程序的输入标志处理错误
In your readtobx routine, there’s conflicting code that messes up the input ready flag:
MOV AX,0x01 MOV [0xF5],BX MOV AX,0x00 MOV [0XF5],AX
This first writes the input value to 0xF5, then immediately overwrites it with 0. You should only clear 0xF5 (the input ready flag) after reading the input value, not write BX to it.
4. 多余的空输出操作
In each 0-handling branch, you have MOV BX,0x00 CALL writebx which outputs a null character (or ASCII '0' depending on your console setup). This is unnecessary—processing a '0' binary digit just means adding 0 to your total, not outputting anything mid-conversion. These calls are cluttering your final output.
修正后的代码
Here's the fixed version with all the above issues addressed:
// Clear memory MOV BX, 0x00 MOV [0xA0],BX MOV [0xA1],BX MOV [0xA2],BX MOV [0xA3],BX MOV [0xA4],BX // Tens digit storage // If equal to 1, write 8 to A0. Else move on CALL readtobx CMP BX,0x31 JEQ bxisone_eight // If equal to 0, write nothing. Else, write E and halt CMP BX,0x30 JNE error JMP wrote8bit bxisone_eight: MOV BX,0x08 MOV [0xA0],BX wrote8bit: // If equal to 1, write 4 to A1. Else move on CALL readtobx CMP BX,0x31 JEQ bxisone_four // If equal to 0, write nothing. Else, write E and halt CMP BX,0x30 JNE error JMP wrote4bit bxisone_four: MOV BX,0x04 MOV [0xA1],BX JMP wrote4bit wrote4bit: // If equal to 1, write 2 to A2. Else move on CALL readtobx CMP BX,0x31 JEQ bxisone_two // If equal to 0, write nothing. Else, write E and halt CMP BX,0x30 JNE error JMP wrote2bit bxisone_two: MOV BX,0x02 MOV [0xA2],BX JMP wrote2bit wrote2bit: // If equal to 1, write 1 to A3. Else move on CALL readtobx CMP BX,0x31 JEQ bxisone_one // If equal to 0, write nothing. Else, write E and halt CMP BX,0x30 JNE error JMP wrote1bit // Fixed: was wrote4bit bxisone_one: MOV BX,0x01 MOV [0xA3],BX JMP wrote1bit wrote1bit: // Add all the numbers together MOV BX,0x00 ADD BX,[0xA0] ADD BX,[0xA1] ADD BX,[0xA2] ADD BX,[0xA3] // Check if total is >=10 MOV AX,0x0A CMP AX,BX JGE write_two_digit // Single digit: convert to ASCII and output ADD BX,0x30 CALL writebx HALT error: MOV BX,0x45 // ASCII 'E' CALL writebx HALT writebx: MOV AX,[0xF2] CMP AX,0x0 JNE writebx MOV [0xF0],BX MOV AX,0x10 MOV [0xF2],AX // Set OSR to 1 RET readtobx: MOV AX,[0xF5] CMP AX,0x00 // Wait for input ready JEQ readtobx MOV BX,[0xF3] // Read input value MOV AX,0x00 MOV [0xF5],AX // Clear input ready flag RET write_two_digit: // Calculate tens digit: subtract 10 until BX <10, count times MOV AX,0x00 tens_loop: CMP BX,0x0A JL write_tens SUB BX,0x0A INC AX JMP tens_loop write_tens: MOV [0xA4],AX // Save tens digit // Output tens digit (ASCII) MOV BX,[0xA4] ADD BX,0x30 CALL writebx // Output ones digit (ASCII) MOV BX,0x00 ADD BX,[0xA4] ADD BX,0x30 CALL writebx HALT
关键修正说明
- Fixed the misjump in the 1-bit section to point to
wrote1bitinstead ofwrote4bit - Rewrote
write_two_digit(formerlywrite10first) to correctly calculate and output tens and ones digits by subtracting 10 repeatedly and counting the tens place - Fixed
readtobxto properly clear the input flag without conflicting writes - Removed the unnecessary
writebxcalls when processing '0' binary digits - Renamed
write10firsttowrite_two_digitfor clarity
Give this version a try—this should handle 4-bit binary inputs (0000 to 1111) and output the correct decimal value, or 'E' if invalid input is detected.
备注:内容来源于stack exchange,提问作者H. Walker

