使用8086汇编语言绘制圆圈

时间:2016-03-01 16:28:04

标签: assembly x86-16

我试图使用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

在汇编程序中尝试 Attempt in Assembler 在Python中尝试 Attempt in Python

提前感谢您的帮助!

2 个答案:

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