如何修改x86汇编代码以支持两位数输入并判断奇偶
改造x86汇编代码以支持两位数输入的奇偶判断
问题分析
原代码仅支持一位数输入的核心问题有两个:
- 用
int 21h的ah=1单次读取单个字符,无法获取多位数输入; - 直接判断输入字符的ASCII码奇偶性,而非数值本身的奇偶性(虽然一位数时巧合正确,但多位数时会出错)。
修改后的完整代码
.model small .stack 100h .data first_prompt db 'Enter first number: $' second_prompt db 10, 13, 'Enter second number: $' third_prompt db 10, 13, 'Enter third number: $' result_msg db 10, 13, 'The results are: $' even_msg db ' is even,', 10, 13, '$' odd_msg db ' is odd,', 10, 13, '$' newline db 0dh, 0ah, '$' input_buf db 3, ?, 3 dup(0) ; 输入缓冲区:长度标识、实际输入长度、2个字符存储位 .code main: mov ax, @data mov ds, ax ; 读取第一个数 mov ah, 9 lea dx, first_prompt int 21h call read_two_digit_num mov [num1], ax mov [num1_char1], bl mov [num1_char2], bh ; 读取第二个数 mov ah, 9 lea dx, second_prompt int 21h call read_two_digit_num mov [num2], ax mov [num2_char1], bl mov [num2_char2], bh ; 读取第三个数 mov ah, 9 lea dx, third_prompt int 21h call read_two_digit_num mov [num3], ax mov [num3_char1], bl mov [num3_char2], bh ; 显示结果标题 mov ah, 9 lea dx, result_msg int 21h ; 处理第一个数的输出与奇偶判断 call display_num_and_parity, num1, num1_char1, num1_char2 ; 处理第二个数 call display_num_and_parity, num2, num2_char1, num2_char2 ; 处理第三个数 call display_num_and_parity, num3, num3_char1, num3_char2 exit_program: mov ah, 9 lea dx, newline int 21h mov ah, 4Ch int 21h ; 子程序:读取1-2位十进制数,返回数值到AX,第一位字符到BL,第二位字符到BH(一位数时BH为空格) read_two_digit_num: ; 使用DOS字符串读取功能 mov ah, 0Ah lea dx, input_buf int 21h ; 获取实际输入的字符长度 mov cl, input_buf[1] xor ch, ch ; 初始化数值寄存器 xor ax, ax ; 转换第一位字符为数值 mov bl, input_buf[2] sub bl, '0' add al, bl ; 如果只有一位数,直接结束转换 cmp cl, 1 je read_single_digit ; 转换第二位字符并计算两位数数值 mov bh, input_buf[3] sub bh, '0' mov bl, 10 mul bl ; AX = 当前数值 *10 add al, bh jmp read_cleanup read_single_digit: ; 一位数时将BH设为空格,避免输出乱码 mov bh, ' ' read_cleanup: ; 输出换行,清理输入后的回车残留 mov ah, 2 mov dl, 0Ah int 21h ret ; 子程序:显示数字并判断奇偶,参数依次为:数值地址、第一位字符地址、第二位字符地址 display_num_and_parity: push bp mov bp, sp ; 输出第一位字符 mov ah, 2 mov dl, [bp+6] int 21h ; 输出第二位字符(如果不是空格) mov dl, [bp+4] cmp dl, ' ' je skip_second_char int 21h skip_second_char: ; 判断数值奇偶性 mov ax, [bp+8] test ax, 1 jz show_even_msg ; 显示奇数提示 mov ah, 9 lea dx, odd_msg int 21h jmp display_done show_even_msg: ; 显示偶数提示 mov ah, 9 lea dx, even_msg int 21h display_done: pop bp ret 6 ; 清理栈上的6字节参数 ; 存储数值与输入字符的变量 num1 dw ? num2 dw ? num3 dw ? num1_char1 db ? num1_char2 db ? num2_char1 db ? num2_char2 db ? num3_char1 db ? num3_char2 db ? end main
核心修改点说明
- 多位数输入处理:改用DOS的
ah=0Ah字符串读取功能,通过缓冲区支持最多2位数字输入,自动识别回车作为输入结束标志。 - 数值转换逻辑:将读取的ASCII字符转换为十进制数值,两位数计算为
十位数字*10 + 个位数字,确保奇偶判断基于实际数值而非字符编码。 - 代码复用:编写两个子程序分别处理输入读取和输出判断,避免重复代码,提升可维护性。
- 奇偶判断修正:通过
test ax,1检查数值的最低位,准确判断奇偶性,解决原代码中基于ASCII码判断的潜在错误。 - 输入兼容:同时支持一位数和两位数输入,输出时自动处理一位数的空格填充,避免显示乱码。
内容的提问来源于stack exchange,提问作者Chiii
相关产品推荐
相关产品推荐

