2016-11-19 99 views
3

您好我一直在試圖使用x86彙編程序使用中點圓算法繪製一個圓,我已經得到它非常接近(我認爲),我跟着另一個非常類似於這個問題:x86彙編Langauge中點圓算法

Drawing a circle using 8086 Assembly Language

這有助於我遇到的其他問題。但是,我並沒有變成一個圓圈,我擁有基本的形狀,但它似乎是凹形的。

[x86 circle] 1

我試圖複製上維基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 

也許我已經完全錯了,任何人都可以幫助我,如果這麼多的應用程序reciated。

謝謝。

回答

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 

必須通過MOV E,AX更換ADD 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 

必須在MUL DX前插入MOV DX,2

我做了兩個修改,現在程序似乎畫了一個圓圈。

順便說一句:

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

+0

感謝您的幫助,我只是嘗試MOV而不幸的是,結果是像一個正方形的形狀,添加斧頭,但是非常感謝,讓我知道我會相應地更改代碼。 – Josh

+0

@Josh我編輯了我的答案。 –

+0

完美我看到了,我忘了使用MUL時它會影響DX。非常感謝你,一直困在那裏。 – Josh