Assembly 额外部分赢得';t在程序集中注册颜色数据
我正在编写一个类似于组装中突破的游戏(工具:DosBOX、notepad++、tasm),在图形模式下创建边框和平台时,我遇到了两个问题:Assembly 额外部分赢得';t在程序集中注册颜色数据,assembly,x86-16,tasm,Assembly,X86 16,Tasm,我正在编写一个类似于组装中突破的游戏(工具:DosBOX、notepad++、tasm),在图形模式下创建边框和平台时,我遇到了两个问题: 似乎额外的片段不会注册颜色信息,因为我无法正确获取它,当我尝试拉它时,它会给我一个0,它是黑色的,而白色是0Fh 这是我试图解决的一个小问题,但由于某种原因,当我尝试绘制第二个和第三个边框时,第一个边框的一部分变为黑色,如果运行代码,您将看到它。我无法确定它发生的原因,调试器也没有显示任何异常 这是我当前的代码,创建边框、平台和移动平台涉及的主要过程是Bor
BorderPaint
、platfuild
和PlatMove
IDEAL
MODEL small
STACK 100h
DATASEG
platLoc dw 63806
speed1 dw 10
speed2 dw 0FFFFh
CODESEG
;procedure to paint borders-6 px white pixels
proc BorderPaint
push ax
push bx
push di
push cx
mov ax,0A000h ;accesses graphics mode video memory
mov es,ax
xor di,di
;first line-left vertical
;sets color white
mov ax,0Fh
mov cx,200 ;enters nested loop
FirstLoop1:
push cx
mov cx,6
SecondLoop1:
mov [es:di],ax
inc di
loop SecondLoop1
sub di,6
add di,320
pop cx
loop FirstLoop1
;second line- up horizontal
mov di,7
mov cx,313
FirstLoop2:
push cx
mov cx,6
SecondLoop2:
mov [es:di],ax
add di,320
loop SecondLoop2
sub di,1920
inc di
pop cx
loop FirstLoop2
mov di,314
mov cx,200
FirstLoop3:
push cx
mov cx,6
SecondLoop3:
mov [es:di],ax
inc di
loop SecondLoop3
sub di,6
add di,320
pop cx
loop FirstLoop3
; xor di,di
; mov ax,0Fh
; mov cx,200
; FirstLoop4:
; push cx
; mov cx,6
; SecondLoop4:
; mov [es:di],ax
; inc di
; loop SecondLoop4
; sub di,6
; add di,320
; pop cx
; loop FirstLoop4
pop cx
pop di
pop bx
pop ax
ret
endp BorderPaint
proc PlatBuild
push di
push cx
push ax
mov di,[platLoc]
mov ax,5
mov cx,40
LoopPaint2:
push cx
mov cx,10
LoopPaint1:
mov [es:di],ax
sub di,320
loop LoopPaint1
add di,320*10
inc di
pop cx
loop LoopPaint2
pop ax
pop cx
pop di
ret
endp PlatBuild
Proc PlatErase
push di
push cx
push ax
mov di,[platLoc]
mov ax,0
mov cx,40
LoopPaint4:
push cx
mov cx,10
LoopPaint3:
mov [es:di],ax
sub di,320
loop LoopPaint3
add di,320*10
inc di
pop cx
loop LoopPaint4
pop ax
pop cx
pop di
ret
endp PlatErase
Proc PlatMove
push ax
push cx
push dx
push di
mov ax,0A000h
mov es,ax
call BorderPaint
;Input
CheckPress1:
mov ah,0h
int 16h
cmp al,'a'
jne nxt11
jmp MoveLeft1
Nxt11:
cmp al,'d'
jne nxt12
jmp MoveRight1
Nxt12:
cmp al,'q'
jne CheckPress1
jmp endproc1
MoveLeft1:
call Delay
mov dx,[platLoc]
add dx,8*320
sub dx,1d
mov di,dx
mov ax,[es:di]
cmp ax,0Fh
jne move1
jmp CheckPress1
move1:
call PlatErase
dec [platLoc]
call PlatBuild
mov ah,1h
int 16h
je MoveLeft1
jmp CheckPress1
MoveRight1:
call Delay
mov dx,[platLoc]
add dx,41
mov di,dx
mov ax,[es:di]
cmp ax,0Fh
jne move2
jmp CheckPress1
move2:
call PlatErase
inc [platLoc]
call PlatBuild
mov ah,1h
int 16h
je MoveRight1
jmp CheckPress1
EndProc1:
pop di
pop dx
pop cx
pop ax
ret
endp PlatMove
proc Delay
push cx
mov cx, [speed2]
LoopLong:
push cx
mov cx, [speed1]
LoopShort:
loop LoopShort
pop cx
loop LoopLong
pop cx
ret
Endp Delay
start:
mov ax,@data
mov ds,ax
mov ax,13h
int 10h
call BorderPaint
call PlatBuild
mov ax, [es:63680]
call PlatMove
exit:
mov ax,4c00h
int 21h
END startenter code here
mov[es:di],ax
将字(两个字节)写入VRAM,ax=0x000F
,因此您可以在[es:di]
值0x0F
和[es:di+1]
值0x00
(黑色)处写入这是亵渎:/<代码>添加di,320-6保持了源代码级别上可见的意图,但也减少了对机器的无知,最大限度地减少了使用的指令量 顺便说一句,如果你想用0x0F值存储6个字节,你也可以存储三个0x0F0F值的字,这样可以节省一半的VRAM访问(这是很昂贵的)。那么
mov-di,
mov cx,
mov-ax,0F0Fh;(同时两个像素)
Draw6PixelsLoop:
mov[es:di],ax
mov[es:di+2],ax
mov[es:di+4],ax
加上di,320
十二月十二日
jnz Draw6PixelsLoop
更理想的硬编码方式是如何绘制6个像素(只有3个VRAM写入)并在下面移动1行
PlatMove
中的VRAM读取单词(两个像素),然后将它们与0Fhcmp ax、0Fh
进行比较,即两个像素“白+黑”=000Fh
。因此,在左侧,这可能会很好地工作,但在右侧,它将仅在边框的末端找到这两个像素(请记住,在右侧的最后一个像素之后,下一个字节是下一行的第一个左像素,因此如果边框的强度为6像素,则第一个白+黑像素位于左边框末端的下一行)dx
寄存器中,您将降落到屏幕下方,因此离开屏幕。实际上,由于段环绕,您将错误地寻址VRAM顶部的一些随机像素
MoveLeft1:
call Delay
mov di, [platLoc]
mov al, [es:di-1] ; Pixel to the left of the platform
cmp al, 0Fh ; Is it white?
jne move1
jmp CheckPress1
move1:
call PlatErase
dec [platLoc]
call PlatBuild
mov ah, 01h
int 16h ; Key pending?
je MoveLeft1
jmp CheckPress1
在MoveRight1代码中,您也读取了错误的地址。平台宽40像素,因此最后一个像素将位于platLoc+39,因此需要检查的像素位于platLoc+40
“…当我试图拉它给我一个0…”-我不确定256色模式。但在16种颜色模式下,从VGA存储器读取和写入的工作方式不同。在16种颜色模式下,不读回以前写的值是正常的。谢谢你,你帮我解决了第二个问题,你的解释澄清了很多事情,但是我仍然坚持我的第一个问题。我没有准确地表达它,但基本上我的问题是,我不知道如何检查地址是否包含白色像素。你可以看到我的尝试,它是用地址减去1得到像素信息,但我总是得到ax=0x0000。我也试着用2减去,但没有用。
mov di,<some VRAM address>
mov cx,<number of lines>
mov ax,0F0Fh ; <color><color> (two pixels at same time)
Draw6PixelsLoop:
mov [es:di],ax
mov [es:di+2],ax
mov [es:di+4],ax
add di,320
dec cx
jnz Draw6PixelsLoop
;second line- up horizontal
mov di,6 ; (6,0) <--- See 1.
mov cx,320-6-6 ; Width <--- See 2.
FirstLoop2:
push cx
mov cx,6 ; Height
SecondLoop2:
mov [es:di],al ; Color 0Fh, Byte from AL instead of word from AX
add di,320 ; Go down 1 line
loop SecondLoop2
sub di,320*6 ; Take back 6 additions of 320
inc di ; Go right 1 pixel
pop cx
loop FirstLoop2
MoveLeft1:
call Delay
mov dx,[platLoc]
add dx,8*320 ???
sub dx,1d
mov di,dx
mov ax,[es:di] ???
cmp ax,0Fh ???
MoveLeft1:
call Delay
mov di, [platLoc]
mov al, [es:di-1] ; Pixel to the left of the platform
cmp al, 0Fh ; Is it white?
jne move1
jmp CheckPress1
move1:
call PlatErase
dec [platLoc]
call PlatBuild
mov ah, 01h
int 16h ; Key pending?
je MoveLeft1
jmp CheckPress1
MoveRight1:
call Delay
mov dx,[platLoc]
add dx,41 ???
mov di,dx
mov ax,[es:di] ???
cmp ax,0Fh ???
MoveRight1:
call Delay
mov di, [platLoc]
mov al, [es:di+40] ; Pixel to the right of the platform
cmp al, 0Fh ; Is it white?
jne move2
jmp CheckPress1
move2:
call PlatErase
inc [platLoc]
call PlatBuild
mov ah, 01h
int 16h ; Key pending?
je MoveRight1
jmp CheckPress1