2016-11-19 5 views
3

안녕하세요, 저는 중립 원 알고리즘을 사용하여 x86 어셈블러를 사용하여 원을 그리려하고 있습니다. 매우 가까이에 있습니다. 생각해 보면이 질문과 매우 다른 비슷한 질문을 한 적이 있습니다.x86 어셈블리 언어 중점 원 알고리즘

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 

전 완전히 잘못되었을 때, 아무리 많은 앱이라도 도움이된다면 recited.

감사합니다.

답변

5

다음 줄은 C 코드와 동일하지 않는 것 : 당신은 MOV E,AX하여 ADD E,AX를 교체해야합니다

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  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