汇编程序读取扇区号异常:输入不同但输出始终一致
问题分析与解决方案:扇区号读取错误导致磁盘扇区读取结果固定
核心问题1:read_decimal子程序返回值传递错误
你的read_decimal子程序存在逻辑错误,导致输入的扇区号根本没有正确传递到主程序:
read_decimal proc PUSH AX ; 保存调用前的AX值 PUSH BX MOV BL, 10 XOR AX, AX ; AX作为累加器计算扇区号 read_decimal_new: CALL read_char CMP DL, CR JE read_decimal_end SUB DL, "0" MUL BL ADD AL, DL JMP read_decimal_new read_decimal_end: MOV DL, AL ; 结果临时存到DL,但后续操作丢失了这个值 POP BX POP AX ; 恢复调用前的AX旧值,计算结果完全丢失 RET read_decimal endp
调用read_decimal后,你执行MOV sector_num, AX,但此时AX是调用子程序前的旧值,不是用户输入的扇区号,这就导致sector_num始终是同一个错误值,每次读取的都是同一个扇区。
修复方案
修改read_decimal,用AX作为返回值传递结果,不需要保存/恢复AX:
read_decimal proc PUSH BX ; 仅保存BX,AX用于返回结果 MOV BL, 10 ; 十进制基数 XOR AX, AX ; 初始化累加器为0 read_decimal_new: CALL read_char CMP DL, CR JE read_decimal_end ; 过滤非数字输入 CMP DL, '0' JB read_decimal_new CMP DL, '9' JA read_decimal_new SUB DL, "0" MUL BL ; AX = AX * 10 ADD AX, DX ; 支持16位扇区号(0-65535) JMP read_decimal_new read_decimal_end: POP BX RET ; AX直接返回计算结果 read_decimal endp
核心问题2:INT 25h的参数认知误区
INT 25h(绝对磁盘读)的参数规范需要注意:
AL: 驱动器号(软盘为0=A、1=B;硬盘为80h=C、81h=D,你的提示信息msg1中"2=C"是错误的,会误导用户输入错误值)CX: 读取扇区数(你设置为1是正确的)DX: 起始逻辑扇区号(从0开始的连续编号,不是DOS的相对扇区号)DS:BX: 数据缓冲区地址(你的设置正确)
另外,INT 25h调用后会把标志寄存器压栈,应该检查CF标志判断读取是否成功:
INT 25h POPF JC disk_error ; 若CF置位,说明读取失败,可添加错误处理逻辑
其他潜在问题
- 当前
read_decimal仅处理8位数值(原代码用AL累加),修改后的版本支持16位扇区号,覆盖更合理的范围 - 原代码未过滤非数字输入,用户输入字母会导致错误的扇区号计算,修复后的代码增加了数字校验
修复后核心代码片段
主程序中调用read_decimal和磁盘读取的部分无需修改,但现在AX会传递正确的扇区号:
; 读取扇区号 CALL read_decimal MOV sector_num, AX ; 磁盘读取(增加错误检查) LEA BX, block MOV AL, drive_num MOV CX, 1 MOV DX, sector_num INT 25h POPF JC disk_error ; 可在此处添加错误提示逻辑 ; 后续输出逻辑不变 XOR DX, DX CALL write_block
内容的提问来源于stack exchange,提问作者Martin Máté Hajc
相关产品推荐
相关产品推荐

