问题描述
我有一个简单的绘图程序,当按箭头键时,像素“蛇”会朝该方向移动。我的问题是程序可以在200x255像素上运行,但是我想使其在200x 320像素上运行。因此,我需要将x坐标存储在16位寄存器中,而不是8位(最大255个像素)。我试图重写它,但是由于像素计算,这东西对我来说有点太先进了,我找不到帮助。
Draw: //I calculate the pixel position like Pixel = Y * 320 + X
pop dx
xor ah,ah
mov al,dh
push dx
mov bx,320
mul bx
pop dx
add al,dl
jnc Pixel
inc ah
Pixel: //Color and stuff
push dx
mov di,ax
mov al,[si]
mov es:[di],al
//我读了输入键,然后决定在哪里显示像素
Left:
pop dx
dec dl
cmp dl,1
jnc Store
inc dl
jmp Store
Right: //I need 320 and 16 bit register here instead of dl
pop dx
inc dl
cmp dl,250
jc Store
dec dl
jmp Store
Up:
pop dx
dec dh
cmp dh,1
jnc Store
inc dh
jmp Store
Down:
pop dx
inc dh
cmp dh,200
jc Store
dec dh
jmp Store
Store:
push dx
jmp Draw
非常感谢您的帮助
解决方法
如您在Draw行中所见:dh用于Y,dl用于X。两者分别是8位和16位寄存器dx的上半部分或下半部分。 cx似乎在您的程序中无处使用。 bp(在其他程序中通常用于访问堆栈上的变量)也可用。
顺便说一句,仅需使用push dx和pop dx才能防止dh和dl被覆盖。乍一看,我将mul视为唯一命令,它将执行此操作。如果未在其他地方使用,则可能不需要cx或bp。
对于push / pop来说,更好的策略可能是保存该值,然后再由mul覆盖,而在不再需要mul的结果后将其还原,而不是每次使用dx都将其加载并存储在堆栈上。 / p>
,如何使绘图程序在200x320像素(而不是200x255)的组件上工作?
这些分辨率看起来非常陌生。通常,我们将其指定为XRes x YRes。
您当前的程序使用字节大小的寄存器DL
表示X,使用DH
表示Y。这适合您的255x200分辨率,其中单个值不得超过255。较大的320x200分辨率,然后将字大小的寄存器CX
用于X,将DX
用于Y。这也是BIOS为指定坐标而选择的。总是顺其自然!
很难理解如何使用堆栈来存储坐标。我想你可以简化一下...
下一个解决方案期望(X,Y)停留在矩形内,该矩形尊重屏幕周围5个像素的边界。根据需要更改数字:
XRES equ 320
YRES equ 200
BORDER equ 5 ; Resolution 320x200 --> X=[5,314] Y=[5,194]
; assuming CX contains X and DX contains Y
Left:
cmp cx,BORDER + 1
cmc
sbb cx,0
jmp Draw
Right:
cmp cx,XRES - BORDER - 1
adc cx,0
jmp Draw
Up:
cmp dx,BORDER + 1
cmc
sbb dx,0
jmp Draw
Down:
cmp dx,YRES - BORDER - 1
adc dx,0
jmp Draw
使用字大小的寄存器,地址的计算现在更加简单:
Draw:
push dx
mov ax,XRES
mul dx ; DX:AX == Y * 320
pop dx
add ax,cx ; AX == Y * 320 + X
mov di,ax
...
如果您不限于8086,那么它将变为:
Draw:
imul di,dx,XRES ; DI == Y * 320
add di,cx ; DI == Y * 320 + X
...