如何输入多位数并基于Dosseg汇编代码实现数值的相等、不等及大小比较?
Hey there! Let's break down your problem into two clear parts first: verifying your existing comparison logic, then modifying the code to handle multi-digit inputs.
Your original code's comparison logic works correctly for single-digit inputs—here's why:
The
int 21h ah=1function returns the ASCII value of the input character (e.g., typing '5' gives0x35, typing '9' gives0x39). For digits 0-9, their ASCII values are ordered exactly the same as their actual numeric values. So when you runcmp bl, cland useje,jge, etc., the jumps correctly reflect equality, greater-than, and less-than relationships for single-digit numbers.
That said, the logic only compares ASCII characters, not actual numeric values—which is why it fails for multi-digit inputs (e.g., '10' as two separate ASCII characters 0x31 and 0x30 can't be compared directly like a single number).
To support multi-digit numbers, we need to:
- Read input characters one by one until the user presses Enter
- Convert the sequence of digit characters into a single numeric value
- Compare the two converted numeric values instead of ASCII characters
Here's the updated code with comments explaining key changes:
Dosseg .model small .stack 100h .data MsgEq db 'Numbers are Equal $' MsgUneq db 'Numbers are Unequal and $' MsgGr db ' First Number is greater than second number $' MsgLs db ' First Number is lesser than second number $' Prompt1 db 'Enter first number: $' Prompt2 db 0Dh, 0Ah, 'Enter second number: $' ; Newline before second prompt .code ; Subroutine: Read multi-digit input and convert to decimal value (stored in AX) ; Input: None (uses int 21h to read characters) ; Output: AX = converted decimal number read_multidigit proc xor ax, ax ; Initialize result to 0 read_loop: mov ah, 1 int 21h ; Read a character into AL cmp al, 0Dh ; Check if user pressed Enter je read_done ; Exit loop on Enter sub al, 30h ; Convert ASCII character to numeric digit ('0'-'9' → 0-9) mov cx, ax ; Temporarily store the new digit mov bx, 10 mul bx ; Multiply current result by 10 (shift left in decimal) add ax, cx ; Add the new digit to the result jmp read_loop read_done: ret read_multidigit endp main proc mov ax, @data mov ds, ax ; Prompt and read first number mov dx, offset Prompt1 mov ah, 9 int 21h call read_multidigit ; First number stored in AX mov bx, ax ; Save first number to BX ; Prompt and read second number mov dx, offset Prompt2 mov ah, 9 int 21h call read_multidigit ; Second number stored in AX mov cx, ax ; Save second number to CX ; Compare the two numeric values cmp bx, cx je EQUAL ; Handle unequal case: newline first mov dl, 0Dh mov ah, 2 int 21h mov dl, 0Ah mov ah, 2 int 21h mov dx, offset MsgUneq mov ah, 9 int 21h cmp bx, cx jge Greater mov dx, offset MsgLs jmp PrintResult Greater: mov dx, offset MsgGr PrintResult: mov ah, 9 int 21h jmp ExitProgram EQUAL: ; Handle equal case: newline first mov dl, 0Dh mov ah, 2 int 21h mov dl, 0Ah mov ah, 2 int 21h mov dx, offset MsgEq mov ah, 9 int 21h ExitProgram: mov ah, 4Ch int 21h main endp end main
Key Changes Explained:
- Added a
read_multidigitsubroutine to handle input conversion:- Starts with a zeroed result, then builds the number by multiplying the current value by 10 and adding each new digit.
- Stops reading when the user presses Enter (
0x0D).
- Replaced direct ASCII comparison with numeric comparison (using
BXandCXto store the converted values). - Added clear prompts to guide the user, and cleaned up newline/carriage return code to avoid repetition.
Notes:
- This code assumes users input valid decimal digits (no letters or symbols). To add error handling, you could check if the input character is between
0x30and0x39(ASCII '0'-'9') and skip invalid characters or show an error message. - The 16-bit
AXregister limits the maximum input value to 65535 (decimal). For larger numbers, you'd need to use a multi-register pair (likeDX:AX) to store the result and adjust the multiplication logic.
内容的提问来源于stack exchange,提问作者Atena

