2016-06-01 15 views
1

Ich versuche jetzt einen Kreis in Assembly zu zeichnen, aber aus irgendeinem Grund funktioniert es nicht, DOSBox friert ein und ich kann nicht zu verstehen, warum. Außerdem erscheint der Kreis nicht auf dem Bildschirm. Ich habe den Großteil des Codes online gefunden und versuche, ihn zu benutzen und zu verstehen, was er tut, aber ich kann hier keine Fehler finden. HierAssembly - Zeichne einen Kreis

ist der Code:

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 

Dank an alle, die helfen.

+1

gegeben wurden Sie mit einem Debugger durch den Code versucht haben, treten? –

+0

Können Sie einen Link zu der Seite posten, auf der Sie diesen Code gefunden haben? –

+0

Wenn Sie Assembler lernen wollen, wählen Sie eine moderne CPU wie Arm. Es ist viel schöner und einfacher zu programmieren. Es gibt Emulatoren und die meisten Handys und die Raspberry-Pi haben diese CPU. (und ich denke, sie verkaufen x86 um etwa 5 zu 1) –

Antwort

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

Mit diesem letzten Befehl call Player1Disc der Code rekursiv und endlos selbst aufrufen, ohne nützlich etwas zu tun! Dies wird unweigerlich das Programm zum Absturz bringen.


Auch wenn der obige Fehler nicht dort die nächsten 2 Zeilen war, den Videomodus auf einen undefinierten Modus eingestellt würden, weil das AL-Register nicht korrekt eingestellt!

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

Vielen Dank für Ihre Hilfe Fifoernik. Ich verstehe nicht, warum das AL-Register nicht richtig eingestellt wurde und wie kann ich die Player1Disc-Funktion stoppen? Der einzige Weg, den ich kenne, ist, es mit etwas zu vergleichen, und ich glaube nicht, dass ich es in diesem Fall verwenden kann. – KatomPower

+4

@KatomPower: klingt für mich wie Sie keine Ahnung haben, was die Anweisungen tun. Versuchen Sie, zu einer Einführung zurückzukehren ... wie zum Beispiel "int 10h" ruft BIOS-Dienste, die "ah" sagt BIOS, welche Art von Service, den Sie verlangen, Rest von Registern muss nach Bedarf eingestellt werden. Von der es = 0xA000 würde ich sagen, dass Sie an 320x200 256 Farbmodus interessiert sind? Die "mov ax, 13h int 10h" wird es tun (ah = 0 [gfx mode wählen), al = 19 [320x200 256color BIOS gfx mode] ... die 'axe' besteht aus' al' und 'ah' Registers, also durch einzelnes 'mov' setzen Sie beide,' al' ist der untere 8-bit Teil) – Ped7g

0

Ich verstehe nicht, was Sie mit dem Programm getan haben, das Sie auf the other forum gefunden haben.
Dies ist, was ich von dort kopiert habe. Es ist so einfach wie nur möglich.

.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 

Um Ihre eigene Version halten Sie die komplette Kreis Verfahren zu korrigieren und mit call Circle nennen. Ich schlage weiter vor, dass Sie das ES Segmentregister innerhalb der Circle Prozedur einrichten, es ist eine robustere Art, Dinge zu tun.

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 
    ... 

Die Gründe, warum Ihre abgestürzt Original-Code bereits von Fifoernik