x86汇编Langauge中点圆算法

Jos*_*osh 3 x86 assembly geometry x86-16

您好我一直在尝试使用x86汇编程序使用中点圆算法绘制一个圆圈,我已经非常接近(我认为),我已经跟着另一个非常类似于这个问题:

使用8086汇编语言绘制圆圈

这有助于解决我遇到的其他问题.但是,我不是一个圆圈,我有基本的形状,但它似乎是凹的.

[x86圈] 1

我试图在wiki上复制C代码示例,如下所示:

C:

void drawcircle(int x0, int y0, int radius)
{
    int x = radius;
    int y = 0;
    int err = 0;

    while (x >= y)
    {
        putpixel(x0 + x, y0 + y);
        putpixel(x0 + y, y0 + x);
        putpixel(x0 - y, y0 + x);
        putpixel(x0 - x, y0 + y);
        putpixel(x0 - x, y0 - y);
        putpixel(x0 - y, y0 - x);
        putpixel(x0 + y, y0 - x);
        putpixel(x0 + x, y0 - y);

        y += 1;
        err += 1 + 2*y;
        if (2*(err-x) + 1 > 0)
        {
            x -= 1;
            err += 1 - 2*x;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ASM:

DSEG    SEGMENT PARA PUBLIC 'DATA'         
    Y       DW  0
    X       DW  0
    Y_C     DW  0
    X_C     DW  0
    E       DW  0
DSEG    ENDS

CSEG    SEGMENT PARA PUBLIC 'CODE'
    ASSUME CS:CSEG, DS:DSEG, SS:SSEG

MAIN    PROC    FAR

    PUSH    DS                         
    MOV     AX,0                       
    PUSH    AX                         
    MOV     AX,DSEG                    
    MOV     DS,AX                      


                            ;The program begins here.
    MOV     AH,00H          ;Video: 640x480
    MOV     AL,18
    INT     10H

    MOV     DX,240
    MOV     CX,320
    MOV     SI,100
    MOV     AL,3
    CALL    CIRCLE


    MOV     AH,00H
    INT     16H

    MOV     AH,00H
    MOV     AL,2            ;Reset the screen to normal
    INT     10H


    RET                                ;The program ends here.

MAIN    ENDP
;--------------------------------------------------------------
;       CIRCLE
;       Description:    Draws a circle
;       Input param:    DX = CENTER (X)
;                       CX = CENTER (Y)
;                       AL = Colour
;                       SI = radius
;       Reg Effected:   None
;--------------------------------------------------------------
CIRCLE      PROC
    PUSH    DX
    PUSH    CX

    MOV     X,SI
    MOV     X_C,DX
    MOV     Y_C,CX

CIR:
    MOV     DX,X
    CMP     DX,Y
    JNGE    FIN_CIR

    CALL    DRAWCIRCLE

    INC     Y

    PUSH    AX

    MOV     AX,2
    MUL     Y
    INC     AX
    ADD     AX,E
    ADD     E,AX

    SUB     AX,X
    MOV     DX,2
    MUL     DX
    INC     AX
    CMP     AX,0
    JG      E_CHECK

    POP     AX
    JMP     CIR

E_CHECK:
    DEC     X
    MOV     AX,X
    MUL     DX
    MOV     DX,1
    SUB     DX,AX
    ADD     E,DX

    POP     AX
    JMP     CIR

FIN_CIR:
    POP     CX
    POP     DX
    RET
CIRCLE      ENDP

;-------------------------------------------------------------
;      DRAWCIRCLE
;       Description:    Draws a circle, using midpoint circle algorithm 
;       Input params:   DX = Row (X)
;                       CX = Column (Y)
;                       AL = Colour
;                       SI = radius
;       Reg Effected:   None
;--------------------------------------------------------------

DRAWCIRCLE      PROC
    PUSH    DX
    PUSH    CX

    MOV     DX,X_C
    MOV     CX,Y_C
    ADD     DX,X
    ADD     CX,Y
    CALL    WRITEPIXEL

    MOV     DX,X_C
    MOV     CX,Y_C
    ADD     DX,Y
    ADD     CX,X
    CALL    WRITEPIXEL

    MOV     DX,X_C
    SUB     DX,Y
    CALL    WRITEPIXEL

    MOV     DX,X_C
    MOV     CX,Y_C
    SUB     DX,X
    ADD     CX,Y
    CALL    WRITEPIXEL

    MOV     CX,Y_C
    SUB     CX,Y
    CALL    WRITEPIXEL

    MOV     DX,X_C
    MOV     CX,Y_C
    SUB     DX,Y
    SUB     CX,X
    CALL    WRITEPIXEL

    MOV     DX,X_C
    ADD     DX,Y
    CALL    WRITEPIXEL

    MOV     DX,X_C
    MOV     CX,Y_C
    ADD     DX,X
    SUB     CX,Y
    CALL    WRITEPIXEL

    POP     CX
    POP     DX
    RET
DRAWCIRCLE      ENDP
Run Code Online (Sandbox Code Playgroud)

也许我已经完全错了,任何人都可以帮助我,如果非常感激.

谢谢.

Mar*_*nau 5

以下行似乎不等于C代码:

MOV     AX,2
MUL     Y 
INC     AX
ADD     AX,E  <- After this AX = err+2*y+1
ADD     E,AX  <- Now you do: err += err+2*y+1
Run Code Online (Sandbox Code Playgroud)

您必须更换ADD E,AXMOV E,AX.

下一个错误就是这个:

    ...
    MOV     DX,2
    MUL     DX    <- This instruction "destroys" DX!
    ...
E_CHECK:
    DEC     X
    MOV     AX,X
    MUL     DX    <- DX is no longer 2 here
Run Code Online (Sandbox Code Playgroud)

你必须在MOV DX,2之前插入一个MUL DX.

我做了两个修改,现在程序似乎画了一个圆圈.

顺便说说:

通过这样做可以更有效地完成乘以2 ADD AX,AX.