如何使绘图程序在 200x320 像素(而不是 200x255)的装配体上工作?
How to make drawing program to work on 200x320 pixels (instead of 200x255) assembly?
我有一个简单的绘图程序,当按下箭头键时,一个像素“蛇”向那个方向移动。我的问题是该程序适用于 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堆栈。
How to make drawing program to work on 200x320 pixels (instead of 200x255) assembly?
这些决议看起来很陌生。通常我们会将其指定为 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
...
我有一个简单的绘图程序,当按下箭头键时,一个像素“蛇”向那个方向移动。我的问题是该程序适用于 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堆栈。
How to make drawing program to work on 200x320 pixels (instead of 200x255) assembly?
这些决议看起来很陌生。通常我们会将其指定为 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
...