【问题标题】:Problems with BIOS delay function (INT 15h / AH = 86h)BIOS 延迟功能问题 (INT 15h / AH = 86h)
【发布时间】:2015-12-04 13:50:07
【问题描述】:

我今年开始在学校学习组装,而我们刚刚开始学习像素。

我们的老师给了我们一些代码并告诉我们乱来,他还告诉我们尝试在代码中实现延迟(ah = 86h | int 15h),但是当我尝试使用它时,位置和颜色一些像素发生了变化,我不明白为什么

代码:(只是一段代码,还有一些延迟后也被毁了)

mov cx,  20

add [y], 2
mov dx, [y]

paint1RowOf10:

mov bh, 0h 
mov bx, cx

add [x], 1
mov cx, [x]

add [y], 4
mov dx, [y]

mov ax, [red]
mov ah,0ch 
int 10h 

    ; here is a delay part, it waits for 1 seconde
    ; from the help of assembly:
    ; INT 15h / AH = 86h - BIOS wait function. 
    ;CX:DX = interval in microseconds (these are notes from my teacher)

mov ah, 86h
mov cx, 1
mov dx, 2
int 15h 

mov cx, bx
loop paint1RowOf10    

这是结果http://prntscr.com/9a8lpw 你能告诉我为什么会这样吗?因为据我所知,像素应该排成一行,而不是改变颜色。

【问题讨论】:

  • 这看起来像一个问题mov bh, 0h;,然后是mov bx, cx。 .首先,将 int 10h/ah=0ch call 的 0 移到 BH (BH=页码)。没关系,然后您就可以通过 mov bx, cx 覆盖所有 BX(包括 BHBL)。 BLBHBX 寄存器的一部分。将某些内容移入 BX 会破坏 BH/BL 。将 CX 压入堆栈(稍后将其弹出)或使用 BX 以外的寄存器作为临时存储(在本例中为 SI 或 DI) 给出的代码看起来很安全。
  • 我说看起来很安全,但您没有显示所有代码,因此它们可能不安全。您必须确保在您显示的代码(以及您没有使用的部分)中没有使用(或将被破坏)您使用的任何内容。最好只修改您的问题以显示您的所有代码,这将使其至少成为一个可验证的完整示例。
  • 如果您想增加获得解决方案的机会,请发布您的所有代码,而不仅仅是 sn-p。尽管显示的代码中存在潜在问题,但如果不查看程序的其余部分,人们将很难提供帮助。
  • 如果没有其余的代码,如果 X 和 Y 被定义为字节(而不是字),那么这里的情况可能会非常糟糕。如果您不觉得有必要提供所有代码,那么我建议您考虑使用调试器单步执行代码(Turbo 调试器做得很合理)
  • Int 15h/AH=86h 在 DOSBox 中有错误。尝试使用视频模式 13 (09h) 而不是 19 (13h)。这在这里有效。

标签: assembly delay dos pixel 16-bit


【解决方案1】:

有一个奇怪的事实,关于 int 15h ah=86h 你还需要设置 al=0,除非它得到一个不稳定的行为

延迟代码:

mov al, 0 mov ah, 86h mov cx, 1 mov dx, 2 int 15h

我用试错法发现了它,当 al=0 时我意识到 它有效。

【讨论】:

    【解决方案2】:

    int 10h 系统/BIOS 调用(不管它是什么)之后,尝试使用调试器确保所有寄存器仍然具有您期望的值。我没有检查文档,但它可能会破坏其他一些寄存器?

    或者你的问题是:

    mov ax, [red]
    mov ah,0ch 
    int 10h
    

    记住ahax 的高半部分。因此,如果您在将某些内容加载到 ax 后立即修改 ah,那么是您的代码修改了您的颜色值。


    还有,类似的代码

    add [y], 2
    mov dx, [y]
    

    太可怕了。尽可能将变量保存在寄存器中。如果您需要溢出一些,请尽量避免使用每次通过循环都会更改的变量。

    mov dx, [y] 
    add dx, 2 
    mov [y], dx
    

    会好一些,因为 dx 将来自第一次加载,而不是读取-修改-写入->加载链。这是更多的指令,这就是为什么将重要的循环变量保存在内存中是不好的。

    【讨论】:

    • al 用于颜色,ah 执行实际操作。之所以这样写,只是因为 red 是 dw,而不是 db,如果是,那就是:mov al, [red] || mov ah,0ch ||整数 10h
    • @user5561744:如果您不想要全部 16b,为什么还要进行 16 位加载? mov al, [red] 如果你只想设置al。如果您需要让 MASM 相信您知道自己在做什么,您可能需要mov al, byte ptr [red]? IDK。
    • @PeterCordes :虽然这是一种糟糕的风格(我完全同意),但他很幸运。颜色只是一个字节(尽管他将其定义为一个词)。重要的部分将被加载到寄存器的下半部分 (AL)。然后他修改 INT 调用的上半部分。因此,尽管这样做的方式不正统且糟糕,但我认为在这种情况下这不是他的问题。我同意将颜色定义为一个字节,然后使用byte ptr
    • @MichaelPetch:我并不是说它不起作用。 :P 我是说它很愚蠢,使人类更难阅读代码。但是,是的,如果你只需要一个字节的存储空间,那么只保留一个。
    • @PeterCordes :我只是指出来。顺便说一句,int 10h/ah=0ch 在返回时不会破坏任何寄存器(因此只需担心会破坏设置输入的寄存器)。 Int 15h/ah=86h 仅在返回时修改 AX
    猜你喜欢
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 1970-01-01
    • 2012-01-31
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多