2016-11-19 4 views
3

こんにちは私は中点サークルアルゴリズムを使ってx86アセンブラを使って円を描こうとしていましたが、私はそれをかなり近づけました(私は思っています)、これと非常に似た別の質問を続けました:x86アセンブリランゲージミッドポイントサークルアルゴリズム

Drawing a circle using 8086 Assembly Language

これは私が遭遇した他の問題に役立っています。しかし、私は円をかなり得ていない、私は基本的な形を持っていますが、それは凹面であるようです。

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 

を多分私は下図のように、私はウィキにCのコード例をコピーしようとしてい

[x86 circle] 1

完全に間違っている、誰でも私が多くのアプリ再発行された。

ありがとうございました。

答えて

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,AXADD 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 DXMOV DX,2を挿入する必要があります。

私は2つの修正を加えました。今ではプログラムが円を描いているようです。ところで

:2を乗じ

ADD AX,AXを行うことによって、より効率的に行うことができます。

+0

助けてくれてありがとう、私はちょうどMOVを試してみました。残念ながら、結果は正方形のような形ですが、追加斧、斧は私に応じてコードを変更することを知らせてくれて大変ありがとうございます。 – Josh

+0

@Josh私は私の答えを編集しました。 –

+0

私はMULを使用するとDXに影響することを忘れていました。そんなに大変ありがとう、ありがとうございます。 – Josh