Warm tip: This article is reproduced from serverfault.com, please click

graphics-无限循环似乎在NASM中不起作用?

(graphics - Infinite loops seemingly not working in NASM?)

发布于 2020-12-21 18:44:22

我正在尝试在NASM中制作一个DOS程序,该程序使用中断10h显示通过左上角的1​​6种可用颜色循环显示的像素。我还使用21h中断,仅使程序每1/100秒(100 fps)运行一次。

segment .data
    pixelcolor: db 0
    pixelx: dw 100
    pixely: dw 100
    timeaux: db 0 ; used later on to force the program to run at 100fps
segment .text
    global _start
    
_start:
    mov ah,00h
    mov al,0dh
    int 10h
    
    mov ah,0bh
    mov bh,00h
    mov bl,00h
    int 10h
    
    .infinite:
        mov ah,2ch
        int 21h ; get system time
        cmp dl,timeaux ; if 1/100 seconds haven't passed yet...
        je .infinite ; ...skip current frame
        ; else, continue normally
        mov byte[timeaux],dl
        
        mov ah,00h
        mov al,0dh
        int 10h
        mov ah,0bh
        mov bh,00h
        mov bl,00h
        int 10h
        
        mov ah,0ch
        mov al,pixelcolor
        mov cx,pixelx
        mov dx,pixely
        int 10h
        inc byte[pixelcolor]
        
        jmp .infinite

但是,当我实际在DOSBox中运行该程序时,像素只是保持红色。有谁知道为什么我的无限循环不起作用?(注意:我对NASM还是很陌生,所以说实话,我什至不惊讶我的程序只能在15%的时间内运行。)

Questioner
NabeGameDev
Viewed
0
Michael Petch 2020-12-22 05:01:08

问题实际上不是循环本身。循环在每次迭代中执行的操作就是问题所在。我遇到的一些问题和观察是:

  • 由于这是一个DOS COM程序,因此你将需要org 100h在顶部,因为DOS加载程序加载了COM程序以使当前程序段的时间偏移100h。否则,你的数据偏移将不正确,从而导致从错误的存储位置读取/写入数据。

  • 你有一个问题mov al,pixelcolor它必须是mov al,[pixelcolor]如果没有方括号1,则将的偏移量pixelcolor移至AL,而不是将偏移量移至ALpixelcolor这同样适用于pixelxpixely你的代码将相同的像素颜色(在你的情况下为红色)重复打印到屏幕上的错误位置2这段代码:

      mov ah,0ch
      mov al,pixelcolor
      mov cx,pixelx
      mov dx,pixely
      int 10h
      inc byte[pixelcolor]
    

    应该:

      mov ah,0ch
      mov al,[pixelcolor]
      mov cx,[pixelx]
      mov dx,[pixely]
      int 10h
      inc byte[pixelcolor]
    
  • 应该注意的是,默认情况下计时器的分辨率仅为每秒18.2倍(〜55ms)。此分辨率比你要的1/100秒要小。

  • 某些版本的DOS可能总是返回0,表示秒值的1/100。

  • 使用BIOS将像素写入屏幕可能会使编码更简单(它可以消除视频模式中的差异),但与直接将像素直接写入内存相比,它的速度将很慢。

  • 我建议使用Borland的Turbo Debugger(TD)调试DOS软件。Turbo Debugger包含在许多Borland的DOS C / C ++编译器套件中


脚注

  • 1[]在NASM中,括号的使用不同于MASM / TASM / JWASM
  • 2尽管你的问题表明你要写入屏幕的左上角,但是代码建议你确实打算在坐标100,100处写入像素。