我试图使用8086汇编程序绘制一个圆圈。我尝试使用midpoint circle algorithm,由于某些原因,遗憾地导致了绘制倾斜的正方形(截图如下)。作为参考,我在python中重写了算法并设法绘制一个没有问题的圆。
我有一种感觉,我的负数操作有问题,但是我的生活无法弄明白,因为Turbo Debugger几乎没有告诉我任何事情。你能引导我朝正确的方向发展吗? 我附上以下代码:
; Program: graph.asm
.MODEL small
.STACK 256
.DATA
.CODE
jmp start
;=========================================
; Basic program to draw a circle
;=========================================
mode db 18 ;640 x 480
x_center dw 300
y_center dw 200
y_value dw 0
x_value dw 100
decision dw 1
colour db 1 ;1=blue
;=========================================
start:
mov ah,00 ;subfunction 0
mov al,mode ;select mode 18
int 10h ;call graphics interrupt
;==========================
mov bx, x_value
sub decision, bx
mov al,colour ;colour goes in al
mov ah,0ch
drawcircle:
mov al,colour ;colour goes in al
mov ah,0ch
mov cx, x_value ;Octonant 1
add cx, x_center ;( x_value + x_center, y_value + y_center)
mov dx, y_value
add dx, y_center
int 10h
mov cx, x_value ;Octonant 4
neg cx
add cx, x_center ;( -x_value + x_center, y_value + y_center)
int 10h
mov cx, y_value ;Octonant 2
add cx, x_center ;( y_value + x_center, x_value + y_center)
mov dx, x_value
add dx, y_center
int 10h
mov cx, y_value ;Octonant 3
neg cx
add cx, x_center ;( -y_value + x_center, x_value + y_center)
int 10h
mov cx, x_value ;Octonant 7
add cx, x_center ;( x_value + x_center, -y_value + y_center)
mov dx, y_value
neg dx
add dx, y_center
int 10h
mov cx, x_value ;Octonant 5
neg cx
add cx, x_center ;( -x_value + x_center, -y_value + y_center)
int 10h
mov cx, y_value ;Octonant 8
add cx, x_center ;( y_value + x_center, -x_value + y_center)
mov dx, x_value
neg dx
add dx, y_center
int 10h
mov cx, y_value ;Octonant 6
neg cx
add cx, x_center ;( -y_value + x_center, -x_value + y_center)
int 10h
inc y_value
condition1:
cmp decision,0
ja condition2
mov cx, y_value
mov ax, 2
imul cx
add cx, 1
inc cx
add decision, cx
mov bx, y_value
mov dx, x_value
cmp bx, dx
ja readkey
jmp drawcircle
condition2:
dec x_value
mov cx, y_value
sub cx, x_value
mov ax, 2
imul cx
inc cx
add decision, cx
mov bx, y_value
mov dx, x_value
cmp bx, dx
ja readkey
jmp drawcircle
;==========================
readkey:
mov ah,00
int 16h ;wait for keypress
;==========================
endd:
mov ah,00 ;again subfunc 0
mov al,03 ;text mode 3
int 10h ;call int
mov ah,04ch
mov al,00 ;end program normally
int 21h
END Start
提前感谢您的帮助!
答案 0 :(得分:0)
您的汇编代码的正方形来自等式:
|x| + |y| = constant
这意味着你的价值不会变得平方
答案 1 :(得分:-1)
; a short program to check how
; set and get pixel color works
name "pixel"
org 100h
PUTC MACRO char
PUSH AX
MOV AL, char
MOV AH, 0Eh
INT 10h
POP AX
ENDM
;;;;;
; first and second number:
num1 dw ?
num2 dw ?
num3 dw ?
start:
lea dx, msg1
mov ah, 09h ; output string at ds:dx
int 21h
; get the multi-digit signed number
; from the keyboard, and store
; the result in cx register:
call scan_num
; store first number:
mov num1, cx ;x coordinate
; new line:
putc 0Dh
putc 0Ah
lea dx, msg2
mov ah, 09h
int 21h
; get the multi-digit signed number
; from the keyboard, and store
; the result in cx register:
call scan_num
; store second number:
mov num2, cx
putc 0Dh
putc 0Ah
lea dx, msg3
mov ah, 09h
int 21h
; get the multi-digit signed number
; from the keyboard, and store
; the result in cx register:
call scan_num
; store third number:
mov num3, cx
mov si,num1 ;x coordinate
mov di,num2 ;y coordinate
mov bp,num3 ;radius
mov ah, 0 ; set display mode function.
mov al, 13h ; mode 13h = 320x200 pixels, 256 colors.
int 10h ; set it!
mov sp,0 ;center point
;radius
;first point
mov bx,1 ;(1-r) condition
sub bx,bp ;same as above
jmp x1
x1:
cmp bx,0 ;condition compare
JL condt1
jmp condt2
condt1:
;increment x by 1
add bx,1;value for P(k+1)
mov ax,2
add sp,1
mul sp
add bx,ax
cmp sp,bp
jae done
mov cx, sp ;1(x,y)
add cx,si ; column
mov dx, bp
add dx,di ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
; pause the screen for dos compatibility:
mov cx, bp ;2(y,x)
add cx,si ; column
mov dx, sp
add dx,di ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
;3 (-x,-y)
mov ax,-1
mul sp
add ax,si
mov cx, ax ; column
mov ax,-1
mul bp
add ax,di
mov dx,ax ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
;4 (-y,-x)
mov ax,-1
mul bp
add ax,si
mov cx, ax ; column
mov ax,-1
mul sp
add ax,di
mov dx,ax ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
mov cx, sp ;5(x,-y)
add cx,si ; column
mov ax,-1
mul bp
add ax,di
mov dx,ax ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
mov cx, bp ;6(y,-x)
add cx,si ; column
mov ax,-1
mul sp
add ax,di
mov dx,ax ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
;7 (-y,x)
mov ax,-1
mul bp
add ax,si
mov cx, ax ; column
mov dx, sp
add dx,di ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
;8(-x,y)
mov ax,-1
mul sp
add ax,si
mov cx, ax ; column
mov dx, bp
add dx,di ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
jmp x1
condt2:
mov ax,2
sub bp,1
mul bp
sub bx,ax
mov ax,2
add sp,1
mul sp
add bx,ax
add bx,1
cmp sp,bp
jae done
mov cx, sp ;1(x,y)
add cx,si ; column
mov dx, bp
add dx,di ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
; pause the screen for dos compatibility:
mov cx, bp ;2(y,x)
add cx,si ; column
mov dx, sp
add dx,di ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
;3 (-x,-y)
mov ax,-1
mul sp
add ax,si
mov cx, ax ; column
mov ax,-1
mul bp
add ax,di
mov dx,ax ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
;4 (-y,-x)
mov ax,-1
mul bp
add ax,si
mov cx, ax ; column
mov ax,-1
mul sp
add ax,di
mov dx,ax ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
mov cx, sp ;5(x,-y)
add cx,si ; column
mov ax,-1
mul bp
add ax,di
mov dx,ax ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
mov cx, bp ;6(y,-x)
add cx,si ; column
mov ax,-1
mul sp
add ax,di
mov dx,ax ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
;7 (-y,x)
mov ax,-1
mul bp
add ax,si
mov cx, ax ; column
mov dx, sp
add dx,di ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
;8(-x,y)
mov ax,-1
mul sp
add ax,si
mov cx, ax ; column
mov dx, bp
add dx,di ; row
mov al, 15 ; white
mov ah, 0ch ; put pixel
int 10h
xor al, al ; al = 0
mov cx, 10 ; column
mov dx, 20 ; row
mov ah, 0dh ; get pixel
int 10h
jmp x1
done:
int 20h
SCAN_NUM PROC NEAR
PUSH DX
PUSH AX
PUSH SI
MOV CX, 0
; reset flag:
MOV CS:make_minus, 0
next_digit:
; get char from keyboard
; into AL:
MOV AH, 00h
INT 16h
; and print it:
MOV AH, 0Eh
INT 10h
; check for MINUS:
CMP AL, '-'
JE set_minus
; check for ENTER key:
CMP AL, 0Dh ; carriage return?
JNE not_cr
JMP stop_input
not_cr:
CMP AL, 8 ; 'BACKSPACE' pressed?
JNE backspace_checked
MOV DX, 0 ; remove last digit by
MOV AX, CX ; division:
DIV CS:ten ; AX = DX:AX / 10 (DX-rem).
MOV CX, AX
PUTC ' ' ; clear position.
PUTC 8 ; backspace again.
JMP next_digit
backspace_checked:
; allow only digits:
CMP AL, '0'
JAE ok_AE_0
JMP remove_not_digit
ok_AE_0:
CMP AL, '9'
JBE ok_digit
remove_not_digit:
PUTC 8 ; backspace.
PUTC ' ' ; clear last entered not digit.
PUTC 8 ; backspace again.
JMP next_digit ; wait for next input.
ok_digit:
; multiply CX by 10 (first time the result is zero)
PUSH AX
MOV AX, CX
MUL CS:ten ; DX:AX = AX*10
MOV CX, AX
POP AX
; check if the number is too big
; (result should be 16 bits)
CMP DX, 0
JNE too_big
; convert from ASCII code:
SUB AL, 30h
; add AL to CX:
MOV AH, 0
MOV DX, CX ; backup, in case the result will be too big.
ADD CX, AX
JC too_big2 ; jump if the number is too big.
JMP next_digit
set_minus:
MOV CS:make_minus, 1
JMP next_digit
too_big2:
MOV CX, DX ; restore the backuped value before add.
MOV DX, 0 ; DX was zero before backup!
too_big:
MOV AX, CX
DIV CS:ten ; reverse last DX:AX = AX*10, make AX = DX:AX / 10
MOV CX, AX
PUTC 8 ; backspace.
PUTC ' ' ; clear last entered digit.
PUTC 8 ; backspace again.
JMP next_digit ; wait for Enter/Backspace.
stop_input:
; check flag:
CMP CS:make_minus, 0
JE not_minus
NEG CX
not_minus:
POP SI
POP AX
POP DX
RET
make_minus DB ? ; used as a flag.
SCAN_NUM ENDP
msg1 db "enter x coordinate: $"
msg2 db "enter y coordinate: $"
msg3 db "enter radius: $"
ten DW 10
ret