Assembly DosBox是一辆有int 15h ah=86h的四轮马车

Assembly DosBox是一辆有int 15h ah=86h的四轮马车,assembly,wait,interrupt,dos,dosbox,Assembly,Wait,Interrupt,Dos,Dosbox,我目前正在编写汇编程序,但我需要让程序每隔一段时间等待一次。 因此,我一直在使用int 15h/ah=86h,但由于某些原因,DosBox给了我一段艰难的时间,程序要么与像素(wierd颜色)混淆,要么更糟;崩溃。 有人能帮我吗?用其他方法替换int 15h,例如,等待“n”秒的过程: 我也有这个问题。根据at的答案,我可以确保在调用中断之前将AL设置为零,从而使其工作: mov counter, 10 L1: mov cx, 0007H mov

我目前正在编写汇编程序,但我需要让程序每隔一段时间等待一次。

因此,我一直在使用int 15h/ah=86h,但由于某些原因,DosBox给了我一段艰难的时间,程序要么与像素(wierd颜色)混淆,要么更糟;崩溃。


有人能帮我吗?

用其他方法替换
int 15h
,例如,等待“n”秒的过程:


我也有这个问题。根据at的答案,我可以确保在调用中断之前将AL设置为零,从而使其工作:

    mov     counter, 10
L1:

    mov     cx, 0007H
    mov     dx, 8480H
    mov     ah, 86h
    mov     al, 0
    int     15h

    mov     dl, '*'
    mov     ah, 02h
    int     21h

    dec     counter
    jnz     L1

(程序打印10个*,每一个之间暂停1秒。)如果没有“mov al,0”,程序将挂起或给出其他未定义的行为,而DOSBox会发出非法读/写消息。通过将al设置为零,程序可以正常工作,但奇怪的是,错误消息仍然出现在DOSBox日志中。

这是DOSBox 0.74.3版中的一个错误。它们的
int15h
处理程序函数的
开关中缺少
break
,因此
ah=86h
处理程序将从一些随机地址复制内存。看见(如果他们打开了
-Wextra
,就会收到编译器警告!)

我想,这似乎是一部电影,但不知何故从未发行过

我已经提交了报告

ah=87h
复制的区域由
cx
中的计数和描述符表中由
es:si
指向的地址指定。如果这些地址超出范围,您应该得到
非法读/写
警告,并且没有其他有害行为,但是如果它们恰好指向实际内存,则可能会覆盖一些重要内容。我怀疑在OP的测试中,目的地恰好指向了视频内存,解释了“奇怪的颜色”


同样,如果
cx=0
,则不会复制任何内容,错误也不会出现。这证明了rkhb删除答案中的解决方法是合理的,即在一个循环中执行小于65毫秒的延迟。

您是否在延迟之前保留寄存器,然后立即恢复它们?也许可以帮助您解决这个问题。我相信DOSBox中的此函数有缺陷。我无法在DOSBox 0.74(Windows 64位)上重现任何奇怪的行为。源代码看起来也很好,乍一看(IRQ 8不得受到阻碍,RTC计时必须是默认的)您能更具体地说明问题的性质吗?我无法想象一个等待函数怎么会使一个程序“与像素混淆”或崩溃。@MargaretBloom:这个程序在DOSBox中完成吗?我的DOSBox在一段时间后挂起,并在状态窗口中显示许多消息,如“从20202000非法读取,CS:IP f000:11c4”。代码是否假定
mov-ah,2ch/int-21h
在不超过1U的时间内完成?例如,假设微秒部分时间与DOS服务调用之间的秒值交叉,则函数将继续跳转。例如,假设*seconds*=99且
dh
返回为12、78、30、90、02、65、20、80。。。类似的。3秒过去了,但函数没有检测到。@MargaretBloom,我理解你的观点,你是对的(像往常一样:)。我的答案是一个盲目的建议,因为OP没有共享他们的代码,所以秒的行为可能是一致的(0,1,2,…)或不规则的(12,38,…),这取决于许多因素。我认为这并没有真正的帮助,除非是偶然的。DOSBox没有查看
al
的内容,错误和不当行为是由我在回答中提到的错误引起的,该错误试图根据其他寄存器的内容及其指向的内存访问内存。我一直在想为什么DOSBox中会存在这种行为。现在我知道了。让我们希望开发人员对您提交的bug报告做出响应。
    mov     counter, 10
L1:

    mov     cx, 0007H
    mov     dx, 8480H
    mov     ah, 86h
    mov     al, 0
    int     15h

    mov     dl, '*'
    mov     ah, 02h
    int     21h

    dec     counter
    jnz     L1