2017-05-22 23 views
1

私はtasmでdosboxを使用しています。スコアシステムが動作しない理由がわかりません

これはアセンブラで書かれたコードの主要部分です。

IDEAL 
MODEL small 
STACK 100h 
P186 

include 'GL1.asm' 

DATASEG 

ballX DW 160 
ballY DW 100 
ballColor DB 4 
BALL_SIZE EQU 20 
ballDeltaX DW ? 
ballDeltaY DW ? 
scorr db 0 

randChangeCounter DW ? 

CODESEG 

start: 
mov ax, @data 
mov ds, ax 
mov ax, 13h 
int 10h 
mov al,[ballColor] 
call glBall 
mov CX,60 
mov [ballDeltaX],-2 
mov [ballDeltaY],-1 
mov cx,300 
call SetCursor 
Gameloop: 
mov BH ,00h 
call TickDelay 

call mouse 

call Score 

cmp [scorr] , 20 
je exit 
call randChange 


call changeOnborder 
call renderBall 

call mouse 
call Score 
cmp [scorr] , 20 
je exit 


jmp Gameloop 
exit: 

mov ah, 0 
mov al, 2 
int 10h 

mov ax, 4c00h 
int 21h 

proc renderBall 
PUSHA 

xor al,al ; balck 
call glBall 

mov cx,[ballDeltaX] 
add [ballX],cx 
mov cx,[ballDeltaY] 
add [ballY],cx 

mov al,[ballColor] 
call glBall 
POPA  
ret 
endp renderBall 

proc waitKey 
PUSHA 
mov ah,00h 
int 16h 
POPA 
ret 
endp waitKey  

proc glBall 
PUSHA 
mov cx,[ballX] 
mov dx,[ballY] 
mov ah,BALL_SIZE 
mov bl,BALL_SIZE 

call glBox 
POPA 
ret 
endp glBall 

proc glBox 
PUSHA 
@@ONE_LINE : 
call glVLine 
inc dx 
dec bl 
jnz @@ONE_LINE 
POPA 
ret 
endp 

proc glVLine 
PUSHA 
mov bl,ah 
mov bh,0 
mov ah,0ch 
@@ONE_PIXEL : 
int 10h 
inc cx 
dec bl 
jnz @@ONE_PIXEL 
POPA 
ret 
endp 

proc randChange 
push ax 
inc [randChangeCounter] 
cmp [randChangeCounter],20 
jne @@skip 
    mov [randChangeCounter],0 

    mov ax,13 ; +-6 
    call rand_max 
    sub ax,6 
    mov [ballDeltaX],ax 

    mov ax,13 ; +-4 
    call rand_max 
    sub ax,6 
    mov [ballDeltaY],ax 

    mov ax,6 
    call rand_max 
    add ax,2 
    mov [ballColor],al 

@@skip: 
pop ax 
ret 
endp randChange 
proc SetCursor 

mov ax, 0h 
int 33h 
mov ax, 1h 
int 33h 
mov ax, 3h 
int 33h 
ret 
endp SetCursor 
proc mouse 
mov ax, 3h 
int 33h 
ret 
endp mouse 
proc Score 

mov ax,3h 
int 33h 
cmp bl,1 
je Check_X1_Cords 
ret 
Check_X1_Cords: 
cmp cx, [ballX] 
jg Check_X2_Cords 
ret 
Check_X2_Cords: 
cmp cx,[ballX+20] 
jl Check_Y1_Cords 
ret 
Check_Y1_Cords: 
cmp dx, [ballY] 
jg ScoreLabel 
ret 
Check_Y2_Cords: 
cmp dx, [ballY+20] 
jl ScoreLabel 
ret 
ScoreLabel: 
inc [scorr] 
ret 
endp Score 

proc changeOnborder 
push ax 

mov ax,[ballX] 
add ax,[ballDeltaX] 
cmp ax,320-BALL_SIZE 
jg X_FIX 
cmp ax,0 
jge X_OK 
X_FIX: 
mov [ballColor],1 
neg [ballDeltaX] 
X_OK: 

mov ax,[ballY] 
add ax,[ballDeltaY] 
cmp ax,200- BALL_SIZE 
jg Y_FIX 
cmp ax,0 
jge Y_OK 
Y_FIX: 
mov [ballColor],1 
neg [ballDeltaY] 
Y_OK: 

pop ax 
ret 
endp changeOnborder 

END start 

、これはGL1.asm

RANDPRIME equ 401 

segment biosdata at 40h 
org 6ch 
timer  dw ? ; clock ticks 
ends 

DATASEG 
lastrand dw 0 


FastCounter DW 0 ; 
SlowCounter DW 0 ; 

CODESEG 

; 
; timeticks - get time ticks from bios data segment. 
; 
; Register Arguments: 
; None. 
; 
; Returns: 
; ax - current ticks 
; 

proc timeticks 
push es 

mov ax, biosdata 
mov es, ax 
assume es:biosdata 
mov ax, [timer] 
assume es:nothing 
pop es 
ret 
endp 

; 
; random - pseudo generate random number 
; 
; Register Arguments: 
; None. 
; 
; Returns: 
; ax - random number. 
; 
codeseg 
proc random 
push dx 
push bx 
mov bx, [lastrand] 
mov ax, bx 
mov dx, RANDPRIME 
mul dx 
mov dx, ax 
call timeticks 
xor ax, dx 
xchg dh, dl 
xor ax, dx 
xchg bh, bl 
xor ax, bx 
mov [lastrand], ax 
pop bx 
pop dx 
ret 
endp 

proc rand_max 
push dx 
push bx 
mov bx,ax ; store max 
call random ; -> ax 
xor dx,dx 
div bx 
mov ax,dx ; the reminder [0..max] 

pop bx 
pop dx 
ret 
endp rand_max 
;===================== Delay ===================== 
Proc delay 

push ax 
push cx 
push dx 
push es 

mov dx,0 
mov cx , 55 
div cx 

mov cx, ax 
cmp cx,0 
je Finish 
DelayLoop: 

call timeticks 
mov dx,ax 
Tick: 
call timeticks 
cmp dx,ax 
je Tick 

loop DelayLoop 
Finish: 

pop es 
pop dx 
pop cx 
pop ax 
ret 
endp Delay 

proc TickDelay 
pusha 

mov cx, 4 
each_sync: 
    call wait_for_vsync 
loop each_sync 

popa 
ret 
endp TickDelay 

proc wait_for_vsync 
pusha 

mov dx, 03dah 
@@previous_not_ended: 
in al, dx 
test al, 08h 
jnz @@previous_not_ended 

@@next_not_started: 
in al, dx 
test al, 08h 
jz @@next_not_started 

@@exit: 
popa 
ret 
endp 

私は問題はGL1であると思いますが、わからないイム何をすべきか分からないです。

問題やコードのスタイルに応じた助けが本当に簡単になります。

ありがとうございます。

+0

あなたのコードが何を期待しますか?代わりにコードは何をしますか?この情報を提供してください。 – fuz

答えて

0

「動作しない」とは何を意味するのか、コードで何をすべきかを理解することは難しいですが、次の部分は意図したことをしていない(おそらく何もコメントしていない) 。

... 
    ; cx = 0..639 mouse.x position 
Check_X1_Cords: 
    cmp cx, [ballX] 
    jg Check_X2_Cords 
    ret 
Check_X2_Cords: 
    cmp cx,[ballX+20] 
    jl Check_Y1_Cords 
    ret 
    ... 

ものはballXシンボルDW(2バイト)予約領域へのメモリアドレスであること、です。たとえば、アドレス0x1234。そしてアドレス0x1234のメモリは、例えば2バイト、0x88 0x01(0x0188 = 392)を含む。そして、のマウスは、その後最初cmpアドレス0x1234(0x0188 = 392)での値でcx(550)を比較しますx位置550

であるとしましょう、とCheck_X2_Cordsjgジャンプを行います。それはあなたが持っているあなたの他の変数を超えて見えるよう

cmp、非常に可能性はない何か有益な(おそらくゼロをメモリ内にありますどのような値であるアドレス0x1234+20 = 0x1248、で値をcx(550)を比較しますが、データセグメント内)。 (シンボリックラベルである、メモリのアドレスをcmp cx,[ballX+20]は、メモリ内の値に20を追加しませんが、それはballXに20を追加します

... 
Check_X2_Cords: 
    add cx,20 
    cmp cx,[ballX] 
    jl Check_Y1_Cords 
    ... 

あなたはおそらくとして、第2のテストを書きたいんでした)、値/変数ではありません。

その命令の本質がmov ax,[offset_of_some_address]あるとして、それはballXのように見えになり、いくつかのアセンブラ(MASM)のサポート構文のようなmov ax,ballXは、それは、IMOちょうど混乱誤謬(ハイレベル言語のように)変数ですされている間ballXはアドレスであり、値ではありません。

他にもエラーがあるかもしれませんが、私は完全なコードレビューをしませんでしたが、最初に私が見た疑いのあるもの(約10秒)で停止しました。すべての乱数を生成して


もう一つの迅速なキャッチ、randomには、いくつかの時間データを使用していますか?やってはいけない、それもバグだ。タイムチックを使用して最初の「シード」値を計算します。その後、ランダムジェネレータが機能します。すべての呼び出しで時間データを混合すると、実際には非ランダムになります。あなたのRANDPRIMEは小さすぎますが、非常にシンプルで高速な(セキュリティ目的には十分ではありませんが、ゲームではうまくいくでしょう)RNGRアルゴリズムの場合、googleは古典的なものです。手順は、すべてのBIOSタイマーを読み取らない

あなた時間刻み:

1

だけで簡単にブラウズは、次のことを明らかにしました!
ESセグメントレジスタのすべてを設定しましたが、mov ax, [timer]命令は完全にDSセグメントレジスタのみに依存します。

これにより、rand_maxの遅延の手順が破棄されます。
それはうまくいきません!別の方法で入れ

時間刻みがおそらく常に同じ値を返すので!)、次が無限ループになっ:

call timeticks 
    mov dx, ax 
Tick: 
    call timeticks 
    cmp dx, ax 
    je Tick 
関連する問題