您好我一直在尝试使用x86汇编程序使用中点圆算法绘制一个圆圈,我已经非常接近(我认为),我跟着另一个非常类似于此问题的问题:
Drawing a circle using 8086 Assembly Language
这有助于解决我遇到的其他问题。但是,我不是一个圆圈,我有基本的形状,但似乎是凹的。
] 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
也许我已经完全错了,如果非常感激,任何人都可以帮助我。
感谢。
答案 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。