我对这段代码有疑问。将图片打印到屏幕时,它会挂起,就像进入无限循环一样。它可以工作,但停止绘图。
另外,当你跳过不断挂起的部分时,会直接报错。
我在互联网上搜索但找不到任何结果。我正在等待您的帮助。
.model small
.stack 64
.DATA
.CODE
screen macro
mov ah,00
mov al,13h
int 10h
endm
clear_screen macro
mov ax,600h
mov bh,07h
mov cx,0
mov bx,184fh
int 10h
endm
yatay macro x,y,c
local myloop
local loop2
mov cx,x
mov dx,y
mov bh,0h
mov bl,5
loop2:
mov [200h],bl
mov [202h],cx
mov bl,5
myloop:
mov ah,0ch
mov al,c
int 10h
inc cx
dec bl
cmp bl,0
jnz myloop
inc dx
mov bl,[200h]
mov cx,[202h]
dec bl
cmp bl,0
jnz loop2
endm
main proc far
mov ax,@data
mov ds,ax
clear_screen
screen
yatay 90d,1d,04
yatay 95d,1d,04
yatay 100d,1d,04
yatay 105d,1d,04
yatay 85d,5d,04
yatay 105d,5d,04
yatay 110d,5d,04
yatay 75d,10d,04
yatay 80d,10d,04
yatay 90d,10d,04
yatay 95d,10d,04
yatay 100d,10d,04
yatay 110d,10d,04
mov ah,4ch
int 21h
main endp
end main
指令
loop2: mov [200h],bl
将bl
复制到DS:200h
处的内存,但您没有在数据段中保留那么多空间,因此您覆盖了其他段中的某些内容,可能会发生奇怪的事情。
图形视频模式 13h (320*200) 使用从地址 A0000h 开始的内存,请参阅这个答案。如果您想通过直接写入视频内存进行绘制,请使用
初始化额外的段寄存器MOV AX,0xA000
MOV ES,AX
例如,用它来每个像素写入一个字节
MOV [ES:DI],AL ; Draw color AL to DI-th pixel.
还要检查您的
clear_screen macro
,它错误地设置了寄存器bx
的内容并覆盖了bh
。当videomode设置为Int 10h/AH=00h时,屏幕已经是干净的,所以不需要clear_screen
。
还有,当你跳过不断挂起的部分时,直接报错
如果你知道程序是哪些部分挂起的,为什么不告诉我们?
您的程序挂起的原因是您正在覆盖程序的指令,正如 vitsoft 的答案中已经解释的那样。
如果您减少对宏的依赖,这种覆盖就不会发生!
您的 yatay 宏扩展到大约 50 个字节,并且您调用该宏 12 次。这意味着您的程序会因为数百个字节而变得臃肿!绘制实心矩形的代码需要成为您的程序可以使用的子例程,也许是为了在小宏中方便起见。
call
在您的绘图代码中,基本上您使用 200h 和 202h 处的内存来临时保存
yatay macro x,y,c
mov cx, x
mov dx, y
mov al, c
call DrawRectangle
endm
和
BL
的寄存器内容。 执行此操作的首选工具是堆栈。只需用
CX
push bx
和 push cx
pop cx
围绕内循环即可。pop bx
这段代码只是需要一些优化。
; IN (al,cx,dx)
DrawRectangle:
mov bh, 0
mov bl, 5
loop2:
push bx
push cx
mov bl, 5
myloop:
mov ah, 0Ch
int 10h
inc cx
dec bl
cmp bl, 0
jnz myloop
pop cx
pop bx
inc dx
dec bl
cmp bl, 0
jnz loop2
ret
main proc far
...
cmp bl, 0
指令本身已经定义了您想要在分支中使用的必要标志。您不需要保留/恢复 dec bl
知道内部循环已将其递增 5 倍,因此恢复只需减去 5 即可。 您不必为内部和外部循环使用相同的计数器寄存器,从而需要保留/恢复。您可以使用额外的寄存器,例如
CX
SI
或 DI
)。您可以使用一条指令加载字大小寄存器的两个字节大小的部分BP
BX
提示:让你的筹码堆更大一点!说
; IN (al,cx,dx)
DrawRectangle:
mov bx, 0005h ; DisplayPage BH=0, OuterCount BL=5
OuterLoop:
mov si, 5
InnerLoop:
mov ah, 0Ch ; BIOS.PutPixel
int 10h
inc cx ; Next X
dec si ; InnerCounter
jnz InnerLoop
sub cx, 5 ; Restore X
inc dx ; Next Y
dec bl ; OuterCounter
jnz OuterLoop
ret
main proc far
...
。