我试图在汇编中的两个点(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之后,我尝试在程序中调用它。它什么都没画,我没有理由说明原因?我知道我使用的像素打印很慢,但这对我此刻的研究来说还不错。 我对汇编中递归的看法是完全错误的,还是有其他原因导致此代码不起作用?
答案 0 :(得分:1)
Frank Kotler是正确的,如果你坚持在堆栈上使用调用参数,那么你有2个选择:
选项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
不要忘记将我的代码转换为汇编程序规范