装配 - 画一个圆圈

时间:2016-06-01 09:20:49

标签: assembly geometry tasm dosbox

我现在正试图在Assembly中绘制一个圆圈,但由于某种原因它不起作用,DOSBox冻结,我似乎无法理解为什么。此外,圆圈不会出现在屏幕上。我在网上发现了大部分代码,我正在尝试使用它并了解它的作用,但我似乎无法在这里找到任何错误。

以下是代码:

player1disccolor db 0Eh
Player1Disc:
    push 0a000h 
    pop es                   
    mov dx, 20               
    mov di, 20               
    mov al, [player1disccolor]               
    mov bx, 30                
    call Player1Disc       
    mov ah, 0 
    int 10h                     
    mov bp,0                 
    mov si,bx                

Disc1:                
    call Set8pixels                             
    sub  bx,bp               
    inc  bp                   
    sub  bx,bp                
    jg   Disc2                  
    add  bx,si                
    dec  si                   
    add  bx,si               

Disc2:                
    cmp si,bp              
    jae Disc1                  
    ret 

Set8pixels:           
    call Set4pixels             

Set4pixels:           
    xchg bp,si               
    call Set2pixels             

Set2pixels:
    neg si 
    push di 
    add di,si 
    add di,dx 
    mov [es:[di+bp]],al 
    sub di,bp 
    stosb 
    pop di 
    ret 

感谢任何帮助过的人。

2 个答案:

答案 0 :(得分:3)

Player1Disc:
    push 0a000h 
    pop es                   
    mov dx, 20               
    mov di, 20               
    mov al, [player1disccolor]               
    mov bx, 30                
    call Player1Disc

使用最后一条指令call Player1Disc,代码递归地并且无休止地调用自己而不做任何有用的事情!这不可避免地会导致程序崩溃。

即使没有上述错误,接下来的2行会将视频模式设置为未定义模式,因为AL寄存器设置不正确!

mov ah, 0 <= This is the BIOS SetVideoMode function
int 10h

答案 1 :(得分:0)

我不明白你对the other forum上找到的程序做了什么 这是我从那里复制的。这很简单。

.MODEL    TINY 
.286 
.CODE 
  ORG       100h 
Start:
  mov       ax,13h 
  int       10h                 ;mode 13h 
  push      0a000h 
  pop       es                  ;es in video segment 
  mov       dx,160              ;Xc 
  mov       di,100              ;Yc 
  mov       al,04h              ;Colour 
  mov       bx,50               ;Radius 
  call      Circle              ;Draw circle 
  mov       ah,0 
  int       16h                 ;Wait for key 
  mov       ax,3 
  int       10h                 ;Mode 3 
  mov       ah,4ch 
  int       21h                 ;Terminate 

;*** Circle 
; dx= x coordinate center 
; di= y coordinate center 
; bx= radius 
; al= colour 
Circle:
  mov       bp,0                ;X coordinate 
  mov       si,bx               ;Y coordinate 
c00:
  call      _8pixels            ;Set 8 pixels 
  sub       bx,bp               ;D=D-X 
  inc       bp                  ;X+1 
  sub       bx,bp               ;D=D-(2x+1) 
  jg        c01                 ;>> no step for Y 
  add       bx,si               ;D=D+Y 
  dec       si                  ;Y-1 
  add       bx,si               ;D=D+(2Y-1) 
c01: 
  cmp       si,bp               ;Check X>Y 
  jae       c00                 ;>> Need more pixels 
  ret 
_8pixels:
  call      _4pixels            ;4 pixels 
_4pixels:
  xchg      bp,si               ;Swap x and y 
  call      _2pixels            ;2 pixels 
_2pixels:
  neg       si 
  push      di 
  add       di,si 
  imul      di,320 
  add       di,dx 
  mov       es:[di+bp],al 
  sub       di,bp 
  stosb 
  pop       di 
  ret 
END Start 

要更正您自己的版本,请保留完整的程序并使用call Circle进行调用。我进一步建议你在 Circle 程序中设置ES段寄存器,这是一种更强大的处理方式。

Player1Disc:
  mov  dx, 20                 ;CenterX
  mov  di, 20                 ;CenterY
  mov  al, [player1disccolor] ;Color              
  mov  bx, 30                 ;Radius
  call Circle
  ...
  ALL THE OTHER CODE YOU NEED
  ...
Circle:
  push 0A000h 
  pop  es                   
  mov  bp, 0                 
  mov  si, bx
  ...

原始代码崩溃的原因已由Fifoernik

提供