是否可以在汇编中移动整个数据块?

时间:2017-01-11 19:14:12

标签: assembly x86-16

我试图制作一个代码来更快地绘制该方块,我想知道是否有可能以某种方式将其放入内存中,当我需要移动它时,只需从内存中取出其他起始坐标?

(整个程序如何工作:当您按下键盘上的箭头时,方块将移动到屏幕的一侧)

    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

1 个答案:

答案 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中设置新的屏幕开始来整个图像,仅绘制一次像素。但是,这个特殊的情况,甚至比调色板技巧更特别,我只是为了完整性而提及它,我不相信这对你来说就足够了。