我试图制作一个代码来更快地绘制该方块,我想知道是否有可能以某种方式将其放入内存中,当我需要移动它时,只需从内存中取出其他起始坐标?
(整个程序如何工作:当您按下键盘上的箭头时,方块将移动到屏幕的一侧)
mov coords, 20*320+100 ;20 line , 100 column
mov ah, 0 ; graphic mode set
mov al, 13h ; 13h = 320x200, 256 colors.
int 10h
;/////// Drawing a Square ////////
mov ax, 0a000h
mov es, ax
mov di,coords
loop:
mov al, 15 ;color, 15 - white
mov cx, 13 ;13 pixels in a row
rep stosw ;loop
inc counter
add di,320-26 ;set pointer to lower line same column as before
cmp counter,25
JNE loop
答案 0 :(得分:0)
首先回答的重要部分:
您当前的解决方案非常接近最佳,stosw
进入VRAM比复制(movsw
)RAM-> VRAM更快,并且比VRAM-> VRAM副本({{更快) 1}}从视频内存中的旧位置到新位置+加上它需要识别重叠区域并通过正确的cld / std传输方向解决...无论如何,尽可能避免读取视频RAM )。
也就是说,如果你每帧会做很多小的矩形和/或有相当大的过度绘制的矩形,在某个阈值之后,最好首先吸入RAM 320x200缓冲区,然后将整个缓冲区复制到VRAM中。这也可以解决由于重叠/过度绘制造成的可见伪影造成的任何闪烁/闪烁,当你的速度不足以在CRT光束之前更新VRAM数据时(在LCD上虚拟,但仍然如此工作,逐行扫描60Hz-per -screen(或你的gfx卡+ lcd支持的刷新率))。
也有一些细节,但首先,为什么8086?它没有多大意义,dosbox可以很容易地模拟386.你是否真的只使用8086的原装PC XT或AT机器?如果您在emu8086中运行,我不会认为它是面向性能的模拟器,它更像是学校教育工具,所以再次切换到dosbox可能会提供更好的速度,即使使用当前代码,再加上它允许你使用80386 +的32b扩展名。
关于代码的细节:
movsw
这应该快一点(比如〜1%)。
在80386上,您可以执行 ; set es + di first of course, this starts where "loop:" was.
; ??? mov al, 15 ;color, 15 - white
mov ax,0A0Fh ; stosw does store "ax", not "al"
; so your code from question does store 0A0F values, not 0F0F. Was it typo?
; anyway, moved outside of loop
mov dx,25 ; row counter
; ^ do NOT use memory when you have spare register available!
align 4
row_loop: ; avoid labels equal to x86 instructions, like "loop"
mov cx, 13 ; 26 pixels in row
dec dx
rep stosw ; set pixels
lea di,[di+320-26] ; address of next line start
jnz row_loop
,这将比rep stosd
快得多,特别是如果您将它与stosw
中的div 4地址对齐...甚至可能是10-30 %快。
如果您在屏幕上只有一个矩形,或者所有内容都以相同的速度/方向移动,您可以使用VGA" X-modes"设置"滚动"通过在VGA中设置新的屏幕开始来整个图像,仅绘制一次像素。但是,这个特殊的情况,甚至比调色板技巧更特别,我只是为了完整性而提及它,我不相信这对你来说就足够了。