x86汇编Langauge中点圆算法

时间:2016-11-19 17:19:11

标签: assembly x86 geometry x86-16

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

Drawing a circle using 8086 Assembly Language

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

[x86 circle] 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;
        }
    }
}

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

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

感谢。

1 个答案:

答案 0 :(得分: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

您必须将ADD E,AX替换为MOV 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

您必须在MOV DX,2之前插入MUL DX

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

顺便说一下:

通过ADD AX,AX可以更有效地完成乘以2。