8086汇编正数检测:按X数组正负给对应Y数组赋值问题求助
8086汇编数组正负判断问题排查与修正
原有代码的核心问题
- 段寄存器未初始化:.MODEL SMALL模式下需要手动给DS寄存器赋值为数据段基址,否则X、Y数组的内存访问会出错
- 输入逻辑错误:仅调用一次
INT 21H AH=1只能读取单个字符的ASCII码,既不支持多位数、负数输入,也没有循环读取10个元素的逻辑,同时读取到的ASCII码没有转换为数值,无法判断正负 - 判断逻辑完全错误:
cmp si,0比较的是X数组的偏移地址而非数组存储的元素值,根本无法判断元素正负 - 赋值逻辑错误:负数分支中错误操作AH寄存器,没有给AL赋值为0就写入Y数组,写入逻辑混乱
- 循环逻辑错误:没有将输入、判断、写入的完整逻辑放入循环体,仅执行一次就结束,循环终止条件判断逻辑也不符合需求
- 输出逻辑错误:直接输出数值1、0而非对应的ASCII码(31H、30H),屏幕上不会显示正确的数字
修正后的可运行代码
.MODEL SMALL .DATA X DW 10 DUP(?) ; 用字存储支持负数和更大的数值 Y DB 10 DUP(?) INPUT_TIP DB 'X : $' OUTPUT_TIP DB 0DH,0AH,'Y : $' SPACE DB ' $' BUFFER DB 6,0,6 DUP(?) ; 输入缓冲区,支持最多5位数字+负号 .CODE START: MOV AX,@DATA MOV DS,AX ; 输出输入提示 LEA DX,INPUT_TIP MOV AH,9 INT 21H MOV CX,10 LEA SI,X LEA DI,Y INPUT_LOOP: ; 调用输入子程序读取数值到AX CALL READ_NUM MOV [SI],AX ; 判断正负 CMP AX,0 JL SET_ZERO SET_ONE: MOV BYTE PTR [DI],1 JMP END_CHECK SET_ZERO: MOV BYTE PTR [DI],0 END_CHECK: ADD SI,2 INC DI ; 输出空格分隔输入的数 LEA DX,SPACE MOV AH,9 INT 21H LOOP INPUT_LOOP ; 输出Y数组 LEA DX,OUTPUT_TIP MOV AH,9 INT 21H MOV CX,10 LEA DI,Y OUTPUT_LOOP: MOV AL,[DI] ADD AL,30H ; 转ASCII MOV DL,AL MOV AH,2 INT 21H LEA DX,SPACE MOV AH,9 INT 21H INC DI LOOP OUTPUT_LOOP MOV AH,4CH INT 21H ; 读取带符号整数到AX的子程序 READ_NUM PROC PUSH BX PUSH CX PUSH DX ; 读取字符串到缓冲区 LEA DX,BUFFER MOV AH,0AH INT 21H ; 初始化 MOV BL,0 ; 符号标记,0正1负 MOV CX,0 LEA SI,BUFFER+2 ; 判断首字符是不是负号 MOV AL,[SI] CMP AL,'-' JNE CONVERT_LOOP MOV BL,1 INC SI CONVERT_LOOP: MOV AL,[SI] CMP AL,0DH ; 回车结束 JE END_CONVERT SUB AL,30H ; CX = CX*10 + AX IMUL CX,10 ADD CX,AX INC SI JMP CONVERT_LOOP END_CONVERT: CMP BL,1 JNE RETURN_NUM NEG CX ; 负数取反 RETURN_NUM: MOV AX,CX POP DX POP CX POP BX RET READ_NUM ENDP END START
代码说明
- 新增了带符号整数输入子程序,支持负数和多位数输入,自动将输入的ASCII字符串转换为数值存储
- 用CX作为循环计数器,确保刚好处理10个数组元素
- 判断元素正负通过比较元素值和0,读取符号标志位实现逻辑分支,对应给Y数组赋值1或0
- 输出时将数值转换为对应的ASCII码后再输出,确保屏幕可以显示正确的数字
- 增加了输入输出提示,和给出的预期运行格式一致
内容的提问来源于stack exchange,提问作者Black White
相关产品推荐
相关产品推荐

