You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TASM中.386模式下解决数据段32位假设及程序崩溃问题

解决你的DOSBox汇编程序问题:.386兼容与跳转优化

我来帮你搞定这两个头疼的问题,先从.386伪指令导致的延迟宏错误说起,再优化那些繁琐的跳转中继。

问题1:切换到.386后Delay宏触发Illegal Read/Write错误

原因分析

当你使用.386伪指令时,汇编器会允许生成32位指令,而DOSBox模拟的是16位实模式环境。你原来用的INT 15h 86h(等待指定时间)功能,在32位指令存在的情况下,DOSBox对寄存器的模拟可能出现冲突——比如误将16位的CX/DX当成32位的ECX/EDX处理,导致非法内存访问。

解决方案:改用兼容16/32位的延迟实现

放弃INT 15h,改用DOS的INT 21h 2Ch功能(获取系统时间)来实现延迟,这个方法在任何实模式汇编环境下都稳定:

delay macro
local wait_loop, check_time
push ax
push dx
mov ah, 2Ch
int 21h          ; 获取当前时间:CH=小时,CL=分,DH=秒,DL=百分秒
mov bl, dl       ; 保存当前的百分秒值
wait_loop:
int 21h          ; 再次读取时间
cmp dl, bl
je wait_loop     ; 直到百分秒发生变化(约10ms延迟)
pop dx
pop ax
endm

如果你坚持想用INT 15h,也可以在宏里显式保存/恢复32位寄存器,避免破坏:

delay macro
push ecx
push edx
mov cx, 0fh
mov dx, 4240h
mov ah, 86h
int 15h
pop edx
pop ecx
endm

问题2:简化繁琐的条件跳转中继

你现在用的to_printHundred: jmp printHundred这种中继完全没必要,可以直接让条件跳转到最终目标标签,省去中间的冗余跳转。

比如原来的代码:

cmp percentage, 64h
je to_printHundred
to_printHundred: jmp printHundred

可以直接改成:

cmp percentage, 64h
je printHundred

这样既简化了代码,又减少了一次跳转的开销,逻辑也更清晰。

修改后的完整代码

这里是整合了两个优化后的完整程序,切换到.386也能正常运行:

.386
.model small
setCurPos macro x,y
pusha
mov ah, 02h
mov bh, 0
mov dl, x
mov dh, y
int 10h
popa
endm
writeChar macro char,color,ctr
pusha
mov ah, 9
mov al, char
mov bh, 0
mov bl, color
mov cx, ctr
int 10h
popa
endm
; 优化后的delay宏
delay macro
local wait_loop, check_time
push ax
push dx
mov ah, 2Ch
int 21h          ; 获取当前时间:CH=小时,CL=分,DH=秒,DL=百分秒
mov bl, dl       ; 保存当前的百分秒值
wait_loop:
int 21h          ; 再次读取时间
cmp dl, bl
je wait_loop     ; 直到百分秒发生变化(约10ms延迟)
pop dx
pop ax
endm
.stack 100h
.data
percentage db 0
ones db ?
tens db ?
.code
org 100
main proc far
mov ax, @data
mov ds, ax
mov es, ax
mov ah, 0
mov al, 13h
mov bh, 0
int 10h
jmp count

count:
delay
cmp percentage, 64h
je printHundred  ; 直接跳转到最终目标,省去中继
cmp percentage, 0ah
jae printTens
;printOnes
mov al, percentage
add al, 30h
mov ones, al
setCurPos 10, 10
writeChar ones, 0fh, 1
inc percentage
jmp count
printTens:
xor ax, ax
mov bx, 0ah
mov al, percentage
div bl
add al, 30h
add ah, 30h
mov tens, al
mov ones, ah
setCurPos 10,10
writeChar tens,0fh,1
setCurPos 11,10
writeChar ones,0fh,1
inc percentage
jmp count
printHundred:
mov tens, 31h
mov ones, 30h
setCurPos 10,10
writeChar tens,0fh,1
setCurPos 11,10
writeChar ones,0fh,2
mov ah, 4ch
int 21h
endp
end main

内容的提问来源于stack exchange,提问作者Mc Henry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:44:39