程序集中的递归线绘图错误?

时间:2013-06-08 15:43:45

标签: assembly recursion drawing x86-16

我试图在汇编中的两个点(x1,y1)和(x2,y2)之间绘制一条线,我决定使用递归线绘制算法而不是Bresenham。我认为这个想法很简单并且编写了代码,但由于某些原因它不起作用。它根本不会在屏幕上绘制任何像素,有时它会抛出非法指令异常。这是代码:

line_recursive proc
    pop dx            ; dx = y1
    pop cx            ; cx = x1
    pop bx            ; bx = y0
    pop ax            ; ax = x0

    cmp dx, bx       ; y1==y0
    jne version1
    cmp ax, cx       ; x1==x0
    je  version2
   version1:
    mov si,ax
    add si,cx
    mov di,bx
    add di,dx
    shr si, 1         ; si = (x1+x0)/2 = x
    shr di, 1         ; di = (y1+y0)/2 = y

    push ax
    push cx
    push dx
    mov ah,0Ch  ;print pixel.
    mov al,12
    mov cx,si
    mov dx,di
    int 10h
    pop dx
    pop cx
    pop ax

    ; stack for call for (x0,y0, x,y)
    push ax
    push bx
    push si
    push di
    ; stack for call for (x1,y1, x,y)
    push cx
    push dx
    push si
    push di

    call line_recursive     ; (x1,y1, x,y)
    call line_recursive     ; (x0,y0, x,y)
   version2:
    ret
line_recursive endp

在将几个数字推到dx,cx,bx和ax之后,我尝试在程序中调用它。它什么都没画,我没有理由说明原因?我知道我使用的像素打印很慢,但这对我此刻的研究来说还不错。 我对汇编中递归的看法是完全错误的,还是有其他原因导致此代码不起作用?

1 个答案:

答案 0 :(得分:1)

Frank Kotler是正确的,如果你坚持在堆栈上使用调用参数,那么你有2个选择:

  1. 更改您的通话顺序
    • 由于需要返回地址标签
    • ,这不是一个很好的选择
  2. 在您的程序中更改参数采集
    • 这是更好的方式
  3. 选项1:

        push adr0
        push x0
        push y0
        push x1
        push y1
        jmp line_recursive
    adr0:
    

    选项2:

    tmp:    dw 0
    line_recursive:
        pop eax           ; eax= return address - not shore if you are using 16/32 bit adress so for 16 bits should be only ax
        pop dx            ; dx = y1
        pop cx            ; cx = x1
        pop bx            ; bx = y0
        pop ax            ; ax = x0
        mov [cs:tmp],ax
        push eax          ; restore return adress - not shore if you are using 16/32 bit adress so for 16 bits should be only ax
        mov ax,[cs:tmp]   ; ax = x0
    
        cmp dx, bx       ; y1==y0
        jne version1
        cmp ax, cx       ; x1==x0
        je  version2
    
    version1:
    
        mov si,ax
        add si,cx
        mov di,bx
        add di,dx
        shr si, 1         ; si = (x1+x0)/2 = x
        shr di, 1         ; di = (y1+y0)/2 = y
    
        push ax
        push cx
        push dx
        mov ah,0Ch  ;print pixel.
        mov al,12
        mov cx,si
        mov dx,di
        int 10h
        pop dx
        pop cx
        pop ax
    
        push ax ; stack for call for (x0,y0, x,y)
        push bx
        push si
        push di
        call line_recursive     ; (x1,y1, x,y)
    
        push cx ; stack for call for (x1,y1, x,y)
        push dx
        push si
        push di
        call line_recursive     ; (x0,y0, x,y)
    
    version2:
        ret
    

    不要忘记将我的代码转换为汇编程序规范

    • 顺便说一句,你忘了提到你使用哪一个,哪个平台,操作系统,型号......