2016-06-01 6 views
1

アセンブリで円を描こうとしていますが、何らかの理由で動作しない場合、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 

ありがとう:ここ

はコードです。この最後の命令 call Player1Discコード付き

+1

によって与えられた理由を、あなたの元のコードがクラッシュした理由は、あなたは、デバッガでコードをステップ実行しようとしたことがありますか? –

+0

このコードを見つけたページへのリンクを投稿できますか? –

+0

アセンブラを学びたい場合は、アームなどの最新のCPUを選択してください。はるかに良く、プログラムしやすくなります。エミュレータとほとんどの携帯電話があり、ラズベリーはこのCPUを持っています。 (そして私は彼らがx86を約5対1で売っていると思う) –

答えて

3

Player1Disc: 
    push 0a000h 
    pop es     
    mov dx, 20    
    mov di, 20    
    mov al, [player1disccolor]    
    mov bx, 30     
    call Player1Disc 
は再帰的に 、有用な何もせずに自分自身を呼び出す延々とです!これは必然的にプログラムをクラッシュさせます。


上記のエラーがなければ、次の2行は、ALレジスタが正しく設定されていないため、ビデオモードを未定義モードに設定します。

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

Fifoernikにお手伝いいただきありがとうございます。 ALレジスタが正しく設定されていない理由と、Player1Disc機能を停止させる方法を理解できません。私が知っている唯一の方法は、それを何かと比較することです。私はこのケースでそれを使うことはできないと思います。 – KatomPower

+4

@KatomPower:あなたは指示が何をしているのか分かりません。いくつかの導入に戻ろうとしましょう。例えば、int 10hがBIOSサービスを呼び出すのと同じように、BIOSがBIOSにどんな種類のサービスを要求しているか、必要に応じて残りのレジスタをサービスごとに設定する必要があります。 es = 0xA000から、320x200 256色モードに興味がありますか? 'mov ax、13h int 10h'はそれを行います(ah = 0 [select gfx mode]、al = 19 [320x200 256color BIOS gfx mode] ...' ax'は 'al'と' ah'の両方から構成されていますしたがって、単一の 'mov'によってそれらの両方を設定し、' al'は下位8ビット部分です) – Ped7g

0

the other forumで見つかったプログラムで行ったことを理解できません。
これは私がそこからコピーしたものです。できるだけ簡単です。完全サークル手順を維持し、call Circleでそれを呼び出す独自のバージョンを修正するには

.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 

。さらに、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