使用递归在MASM中填充封闭区域的颜色

问题描述 投票:0回答:1

我有一个函数 vmem,用于在 (cx, dx) 处绘图。函数 vmemr 用于读取 (cx, dx) 以查看像素是否被绘制。如果 (cx, dx) 上有颜色,则 vmemr 将返回 al=1 现在我想使用递归来填充封闭区域。起点 (cx, dx) 是从封闭区域的中点开始:

fill PROC
    mov al, 0
    push cx
    push dx
    call vmem
    inc cx
    call vmemr
    cmp al, 0
    jne notr
    call fill
notr:    
    dec cx
    dec cx
    call vmemr
    cmp al, 0
    jne notl
    call fill
notl:
    inc cx
    inc dx
    call vmemr
    cmp al, 0
    jne notu
    call fill
notu:
    dec dx
    dec dx
    call vmemr
    cmp al , 0
    jne notd
    call fill
notd:
    pop dx
    pop cx
    
    ret    
fill ENDP

我已经尝试过这段代码。但只是画了一条线,并没有正常退出。

recursion assembly masm
1个回答
0
投票

这个程序看起来没问题。问题可能出在

vmem
vmemr
内部。

  • 错误的像素偏移计算。
  • push/pop,ret指令从堆栈中弹出错误地址。

我添加了其余的代码,它可以正常工作。按任意键查看像素是如何绘制的。

代码:

.model small
.stack 0ffh

.data
    color db 48
.code
start:
    mov ax,@data                    ; load ds
    mov ds,ax

    mov ax,0a000h                   ; es = video mem, offset a000h
    mov es,ax
    
    mov ax,13h                      ; video mode 13h, 320x200x256
    int 10h
    
    call draw_shape                 ; draw rectangle
    
    mov cx, 115                     ; center of the shape
    mov dx, 35
    call fill
    
    mov ax, 4c00h                   ; end app
    int 21h

;-----------------------------------

vmem proc                           
    push dx                         
 
    mov bl,color
    sub bl,6
        
    mov ax,320                       
    mul dx
    add ax,cx
    mov di,ax
    
    mov es:[di],bl
    
    pop dx
    ret
vmem endp

vmemr proc
    push dx
    
    mov ax,320
    mul dx
    add ax,cx
    mov di,ax
    
    mov al,es:[di]
    
    pop dx
    ret
vmemr endp

fill proc
    mov al, 0
    push cx
    push dx
    call vmem
    
    mov ah,08h
    int 21h
    
    inc cx
    call vmemr
    cmp al, 0
    jne notr
    call fill
notr:    
    dec cx
    dec cx
    call vmemr
    cmp al, 0
    jne notl
    call fill
notl:
    inc cx
    inc dx
    call vmemr
    cmp al, 0
    jne notu
    call fill
notu:
    dec dx
    dec dx
    call vmemr
    cmp al , 0
    jne notd
    call fill
notd:
    pop dx
    pop cx
    
    ret    
fill endp

draw_shape proc

    mov di, 320*20 + 100            ; top horizontal line starting position
    mov bx, 320*50 + 100            ; bottom horizontal line starting position
    mov al, color                   ; border color
    
    mov cx,30                       ; draw 30 pixels
    
    hz_lines:
    
        mov es:[di],al              ; upper line pixel
        mov es:[bx],al              ; bottom line pixel
    
        inc di                      ; next pixel
        inc bx                      ;
        
        dec cx                      ; 
        jnz hz_lines                ;

    mov di, 320*21 + 100            ; left vertical line starting position
    mov bx, 320*21 + 129            ; right vertical line starting position
    mov al, 48                      ; border color
    
    mov cx, 29                      ; draw 29 pixels
    
    vt_lines:
    
        mov es:[di],al              ; left line pixel
        mov es:[bx],al              ; roght line pixel
    
        add di,320                  ; next row
        add bx,320                  ;
        
        dec cx                      ;
        jnz vt_lines                ;

    ret
draw_shape endp

end start
end
© www.soinside.com 2019 - 2024. All rights reserved.