Drawing a circle using 8086 Assembly Language [closed]

佐手、 提交于 2019-12-10 10:57:55

问题


I was trying to draw a circle using 8086 assembler. I tried utilizing the midpoint circle algorithm which sadly resulted in drawing a tilted square for some reason (screenshots below). For reference, I rewrote the algorithm in python and managed to draw a circle without a problem.

I have a feeling that there is something wrong with my negative numbers manipulation but can't for the life of me figure it out because Turbo Debugger is telling me literally nothing. Could you guide me in the right direction? I enclose the code below:

; 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 Attempt in Python

Thanks in advance for help!


回答1:


the square which is your assembly code drew comes from equation :

|x| + |y| = constant 

This means your values are not getting squared




回答2:


; 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


来源:https://stackoverflow.com/questions/35728180/drawing-a-circle-using-8086-assembly-language

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!