加载FAT的汇编函数在PCem模拟器触发CPU挂起的原因是什么?
问题核心原因
PCem对8086实模式的硬件行为、汇编指令语义模拟比QEMU、PCjs更严格,你的代码存在以下几个未触发宽松模拟器报错,但会在真实硬件/严格模拟器上崩溃的问题:
1. 复位驱动器函数存在汇编语法错误,破坏中断向量表
resetdrive函数中你写了错误的操作数顺序与大小修饰符:
; 错误写法 mov byte dl,[drive_num]
在NASM/TASM语法中,该指令会被错误解析为将drive_num变量的值写入内存地址为dl的1字节位置。BIOS启动时dl存储的是软盘驱动器号(通常为0x00),因此这行代码实际是往0x0000:0x0000地址(对应中断向量表的除法错误中断入口)写入数据,直接破坏中断向量表。后续调用int 13h、int 10h等BIOS中断时就会触发不可预期的行为,最终导致CPU挂起。
正确写法应为:
mov dl, [drive_num]
2. 读扇区错误处理逻辑栈不平衡
readsectorerror错误处理分支的栈操作存在严重问题:
当int 13h读出错触发跳转时,栈顶存储的是readsectors函数的返回地址,你直接执行pop dx会把返回地址弹出丢弃,后续调用resetdrive再跳回readsectors时,栈会凭空少2字节。每次读出错就会导致栈指针向下偏移2字节,很快就会发生栈溢出,覆盖代码段或其他关键数据导致挂起。
正确处理逻辑应该是先平衡栈:
readsectorerror: pop ax ; 先弹出readsectors的返回地址丢弃 call resetdrive jmp short readsectors
3. LBA转CHS函数无意义清零dl
lbatochs函数末尾的mov dl,0操作完全无必要,虽然当前readsectors会重新赋值dl,但如果后续其他逻辑调用该函数,会导致驱动器号丢失,引发不可预期的错误。
内容的提问来源于stack exchange,提问作者apersonwithacompiler
相关产品推荐
相关产品推荐

