assembly 有没有一种方法来检查特定的内存位置,在汇编,使蛇在蛇游戏的增长对emu8086?

exdqitrt  于 2023-06-06  发布在  其他
关注(0)|答案(1)|浏览(118)
org     100h

jmp     start

s_size  equ     7       

snake dw s_size dup(0)

tail    dw      ?

left    equ     4bh
right   equ     4dh
up      equ     48h
down    equ     50h       

cur_dir db      right

wait_time dw    0

msg1    db "                                  Snake game", 0dh,0ah,0ah
    
    db "                        Yilani on oklari ile kontrol et.", 0dh,0ah,0ah  
    db "                         Duvarlara degersen yanarsin!!!", 0dh,0ah, 0ah  
    db "                            Esc programi sonlandirir.", 0dh,0ah,0ah,0ah
    db "                           Baslamak icin bir tusa bas.$"


msg3  db "", 0dh,0ah, 0ah,0ah, 0ah,0ah,0ah, 0ah,0ah,0ah, 0ah,0ah,0ah, 0ah,0ah, 0ah, 0ah, 0ah,               
db "                                  !!GAME OVER!!", 0dh,0ah,0ah, 0ah, 0ah, 0ah,0ah, 0ah,0ah,      
db " $"
start:       

; print welcome message:
mov     dx, offset msg1
mov     ah, 9 
int     21h

; wait for any key:
mov ah, 00h
int 16h 

mov ax, 0xB800  ; Video memory segment
mov es, ax      ; Set ES segment to video memory

es: mov [09b4h],'?'
es: mov [0848h],'0'
es: mov [06b0h],'0' 
es: mov [01E8h],'0'

; hide text cursor:
mov     ah, 1
mov     ch, 2bh
mov     cl, 0bh
int     10h           

game_loop:

; === select first video page
mov     al, 0  
mov     ah, 05h
int     10h

mov     dx, snake[0]

; set cursor at dl,dh
mov     ah, 02h
int     10h

; print 'o' at the location:
mov     al, 'o'
mov     ah, 09h
mov     bl, 0eh 
mov     cx, 1  
int     10h

; === keep the tail:
mov     ax, snake[s_size * 2 - 2]
mov     tail, ax

call    move_snake

; === hide old tail:
mov     dx, tail

; set cursor at dl,dh
mov     ah, 02h
int     10h

; print '.' at the old location:
mov     al, ' '
mov     ah, 09h
mov     bl, 0eh 
mov     cx, 1  
int     10h


check_for_key:

; === check for player commands:
mov     ah, 01h
int     16h
jz      no_key

mov     ah, 00h
int     16h

cmp     al, 1bh    ; esc - key?
je      stop_game  ;

mov     cur_dir, ah

no_key:

; === wait a few moments here:
; get number of clock ticks
; (about 18 per second)
; since midnight into cx:dx
mov     ah, 00h
int     1ah
cmp     dx, wait_time
jb      check_for_key
add     dx, 4
mov     wait_time, dx


; === eternal game loop:
jmp     game_loop

stop_game:

; show cursor back:
mov     ah, 1
mov     ch, 0bh
mov     cl, 0bh
int     10h

ret

move_snake proc near

; set es to bios info segment:  
mov     ax, 40h
mov     es, ax

  ; point di to tail
  mov   di, s_size * 2 - 2
  ; move all body parts
  ; (last one simply goes away)
  mov   cx, s_size-1
move_array:
  mov   ax, snake[di-2]
  mov   snake[di], ax
  sub   di, 2
  loop  move_array

cmp     cur_dir, left
  je    move_left
cmp     cur_dir, right
  je    move_right
cmp     cur_dir, up
  je    move_up
cmp     cur_dir, down
  je    move_down

jmp     stop_move       ; no direction.

move_left:
  mov   al, b.snake[0]
  dec   al
  mov   b.snake[0], al

  cmp   al, -1
  jne   stop_move       
  mov   al, es:[4ah]    ; col number.
  dec   al
  call game_over  ; return to right. 
  
  jmp   stop_move

move_right:
  mov   al, b.snake[0]
  inc   al
  mov   b.snake[0], al 
  cmp   al, es:[09b4h]
  cmp   al, es:[4ah]    ; col number. 
  jb    stop_move
  call game_over   ; return to left.    
  jmp   stop_move

move_up:
  mov   al, b.snake[1]
  dec   al
  mov   b.snake[1], al
  cmp   al, -1
  jne   stop_move
  mov   al, es:[84h]    ; row number -1.
  call game_over  ; return to bottom.     
  jmp   stop_move

move_down:
  mov   al, b.snake[1]
  inc   al
  mov   b.snake[1], al
  cmp   al, es:[84h]    ; row number -1.
  jbe   stop_move
  call game_over   ; return to top.   
  jmp   stop_move

stop_move:

ret      

grow_snake:

ret

    
game_over: 

mov     dx, offset msg3
mov     ah, 9 
int     21h

; wait for any key:
mov ah, 00h
int 16h   

  
move_snake endp

我尝试在snake到达这些内存位置时将其增长:

es: mov [09b4h],'?'
es: mov [0848h],'0'
es: mov [06b0h],'0' 
es: mov [01E8h],'0'

但是我做不到。我的第一个计划是在stop_game中检查它,并在那里调用grow_snake,但无论我如何尝试,我都没有工作。但是不能对grow_snake部分triend到inc_size做任何事情,但是它也不工作。
我该如何检查snake是否到达了我打印的东西的内存位置并相应地增长?
谢谢你。

zour9fqk

zour9fqk1#

更新
如果你不介意的话,我在屏幕上打印了蛇的头后写了CheckFood proc。它将head的XY坐标转换为内存中的偏移量,并搜索数组targetInMem中是否存在相同的地址。

org     100h

    jmp     start

    s_size  equ     7       

    snake dw s_size dup(0)

    tail    dw      ?

    left    equ     4bh
    right   equ     4dh
    up      equ     48h
    down    equ     50h       

    targetInMem dw 09b4h,0848h,06b0h,01E8h 

    cur_dir db      right

    wait_time dw    0

    Food1  db "Food 1                       ", 0dh,0ah,'$'
    Food2  db "Food 2                          ", 0dh,0ah,'$'
    Food3  db "Food 3                          ", 0dh,0ah,'$'
    questMark  db "Question mark", 0dh,0ah,'$'

    msg1    db "             Snake game",0dh,0ah,0ah
            db "       Yilani on oklari ile kontrolet.",0dh,0ah,0ah  
            db "          Duvarlara degersen yanarsin!!!", 0dh,0ah, 0ah  
            db "  Esc programi sonlandirir.", 0dh,0ah,0ah,0ah
            db "                           Baslamak icin bir tusa bas.$"

    msg3  db "", 0dh,0ah, 0ah,0ah, 0ah,0ah,0ah, 0ah,0ah,0ah, 0ah,0ah,0ah, 
          db "                                  !!GAME OVER!!", 0dh, 0ah, 
          db 0ah, 0ah, 0ah, 0ah,0ah, 0ah,0ah," $"

    start:       
    mov ax,0003h
    int 10h
    ; print welcome message:
    mov     dx, offset msg1
    mov     ah, 9 
    int     21h

    ; wait for any key:
    mov ah, 00h
    int 16h 

    mov ax, 0xB800  ; Video memory segment
    mov es, ax      ; Set ES segment to video memory

    es: mov [09b4h],'?'
    es: mov [0848h],'1'
    es: mov [06b0h],'2' 
    es: mov [01E8h],'3'

    ; hide text cursor:
    mov     ah, 1
    mov     ch, 2bh
    mov     cl, 0bh
    int     10h           

    game_loop:

    ; === select first video page
    mov     al, 0  
    mov     ah, 05h
    int     10h

    mov     dx, snake[0]

    ; set cursor at dl,dh
    mov     ah, 02h
    int     10h

    ; print 'o' at the location:
    mov     al, 'o'
    mov     ah, 09h
    mov     bl, 0eh 
    mov     cx, 1  
    int     10h

    call CheckFood

    ; === keep the tail:
    mov     ax, snake[s_size * 2 - 2]
    mov     tail, ax

    call    move_snake

    ; === hide old tail:
    mov     dx, tail

    ; set cursor at dl,dh
    mov     ah, 02h
    int     10h

    ; print '.' at the old location:
    mov     al, ' '
    mov     ah, 09h
    mov     bl, 0eh 
    mov     cx, 1  
    int     10h

    check_for_key:

    ; === check for player commands:
    mov     ah, 01h
    int     16h
    jz      no_key

    mov     ah, 00h
    int     16h

    cmp     al, 1bh    ; esc - key?
    je      stop_game  ;

    mov     cur_dir, ah

    no_key:

    ; === wait a few moments here:
    ; get number of clock ticks
    ; (about 18 per second)
    ; since midnight into cx:dx
    mov     ah, 00h
    int     1ah
    cmp     dx, wait_time
    jb      check_for_key
    add     dx, 4
    mov     wait_time, dx

    ; === eternal game loop:
    jmp     game_loop

    stop_game:

    ; show cursor back:
    mov     ah, 1
    mov     ch, 0bh
    mov     cl, 0bh
    int     10h

    ret

    move_snake proc near

    ; set es to bios info segment:  
    mov     ax, 40h
    mov     es, ax

    ; point di to tail
    mov   di, s_size * 2 - 2
    ; move all body parts
    ; (last one simply goes away)
    mov   cx, s_size-1
   move_array:
   mov   ax, snake[di-2]
   mov   snake[di], ax
   sub   di, 2
   loop  move_array

   cmp     cur_dir, left
   je    move_left
   cmp     cur_dir, right
   je    move_right
    cmp     cur_dir, up
   je    move_up
   cmp     cur_dir, down
   je    move_down

   jmp     stop_move       ; no direction.

    move_left:
    mov   al, b.snake[0]
    dec   al
    mov   b.snake[0], al

    cmp   al, -1
    jne   stop_move       
    mov   al, es:[4ah]    ; col number.
    dec   al
    call game_over  ; return to right. 
  
    jmp   stop_move

    move_right:
    mov   al, b.snake[0]
    inc   al
    mov   b.snake[0], al 
    cmp   al, es:[09b4h]
    cmp   al, es:[4ah]    ; col number. 
    jb    stop_move
    call game_over   ; return to left.    
    jmp   stop_move

    move_up:
    mov   al, b.snake[1]
    dec   al
    mov   b.snake[1], al
    cmp   al, -1
    jne   stop_move
    mov   al, es:[84h]    ; row number -1.
    call game_over  ; return to bottom.     
    jmp   stop_move

    move_down:
    mov   al, b.snake[1]
    inc   al
    mov   b.snake[1], al
    cmp   al, es:[84h]    ; row number -1.
    jbe   stop_move
    call game_over   ; return to top.   
    jmp   stop_move

    stop_move:

    ret      

    grow_snake:

    ret

    CheckFood: 
       pusha
   
       xor ax,ax        ;calculate head position
       mov al,dh;[yPos]
        mov cl,80
        mul cl 
        xor cx,cx
        mov cl,dl;[xPos]   
        add ax,cx    ; ax offset in mem   
        mov cx,2
        mul cx
   
        mov bx, offset targetInMem
        mov cx,4
   
        push dx       
      
      MemSearch:       ;search array, what snake eat    
      mov dx,[bx]       
      cmp dx,ax
      jz PrintMsg
      add bx,2
      loop MemSearch  
       
      jmp NoFood
      
      PrintMsg:
         ; set cursor at dl,dh
        mov ah, 2
        mov bh,0
        mov dx, 1010h
        int 10h 
        
        cmp cx,4           
        jz msgFood1
        cmp cx,3           
        jz msgFood2
        cmp cx,2           
        jz msgFood3
        cmp cx,1           
        jz qMark        
        jmp NoFood
        
        msgFood1:
            mov     dx, offset questMark
            mov     ah, 9 
            int     21h                
            jmp NoFood
            
        msgFood2:
            mov     dx, offset Food1
            mov     ah, 9 
            int     21h                
            jmp NoFood
                    
        msgFood3:
            mov     dx, offset Food2
            mov     ah, 9 
            int     21h                
            jmp NoFood              
            
        qMark:
            mov     dx, offset Food3 
            mov     ah, 9 
            int     21h                 
            
      NoFood:          
         pop dx  
        
    popa    
ret
    
game_over: 

mov     dx, offset msg3
mov     ah, 9 
int     21h

; wait for any key:
mov ah, 00h
int 16h   
  
move_snake endp

我不知道这是否是你的答案。这仅仅是一个例子。屏幕坐标转换为视频内存偏移。

xor ax,ax        ;calculate head position
   mov al,[yPos]
   mov cl,80
   mul cl 
   xor cx,cx
   mov cl,[xPos]   
   add ax,cx    
   mov cx,2
   mul cx
   
   mov cx,[targetInMem]
   cmp cx,ax
   jz game_over

下面的例子

org     100h

jmp     start

s_size  equ     7       

snake dw s_size dup(0)

tail    dw      ?  
Head    db      79 
KeyNumber db      ?
xPos db 2           ;cursor x position on screen    
yPos db 2           ;cursor y position on screen    
targetX  db  13
targetY  db  3
targetInMem  dw 01fah 

msg1    db "Use arrows.  $"     

msg2  db "Target reached!$"

msg3  db "!!GAME OVER!!$"

          ;;;Macros
          
          SetCharAttrib MACRO char,attr       
            push bx
            push ax
            push dx
            push cx

            mov ah,9
            mov al,char
            mov cx,1
            ;mov dl,y
            ;mov dh,x
            mov bh,0 
            mov bl,attr
            int 10h
            
            pop cx
            pop dx
            pop ax
            pop bx
          ENDM 
          
        SetCursor MACRO x,y
        
            push bx
            push ax
            push dx
            push cx

            mov ah,02h
            mov dl,x
            mov dh,y
            mov bh, 00h 
            int 10h

            pop cx
            pop dx
            pop ax
            pop bx
        ENDM          

start:    
   mov ax,0003h
   int 10h

    mov ax, 0xB800  ; Video memory segment
    mov es, ax      ; Set ES segment to video memory

    es: mov [01fah],'X' ;506
    ; print welcome message:
    mov     dx, offset msg1
    mov     ah, 9 
    int     21h

    ; hide text cursor:
    mov     ah, 1
    mov     ch, 2bh
    mov     cl, 0bh
    int     10h           
            
    ;set cursor position            
    SetCursor [xPos],[yPos]          
    
    SetCharAttrib 79,14                  
                              
    game_loop:
                      
    ; wait for any key:
        call CheckKey

        cmp al,27       ;Esc, exit program
        jz stop_game
    
    
  ;SetCursor [xPos]+12,[yPos]     

   call BoardAction 
   
   SetCharAttrib 0,0   
   
   SetCursor [xPos],[yPos]          
    
   SetCharAttrib 79,14              
   
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  
 ;;;;  Translate from screen coords
 ;;;;  to video mem adress  
 
   xor ax,ax        ;calculate head position
   mov al,[yPos]
   mov cl,80
   mul cl 
   xor cx,cx
   mov cl,[xPos]   
   add ax,cx    
   mov cx,2
   mul cx
   
   mov cx,[targetInMem]
   cmp cx,ax
   jz game_over

 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  

; === eternal game loop:
    jmp     game_loop

stop_game:

; show cursor back:
mov     ah, 1
mov     ch, 0bh
mov     cl, 0bh
int     10h
jmp game_over

CheckKey Proc
    
    mov ah,0
    int 16h
          
    cmp al,0
    jz Extended
    jmp Normal
    
    Extended:      
        mov [KeyNumber], ah
         mov al,ah
    jmp NextTurn
    
    Normal:                       
        mov [KeyNumber], al
                                   
    NextTurn:   
    ret
CheckKey Endp

BoardAction Proc
                            
    cmp al,77      ;right arrow
    jz moveRight                 
    cmp al,75      ;left arrow
    jz moveLeft
    cmp al,72      ;up arrow
    jz moveUp             
    cmp al,80      ;down arrow
    jz moveDown
    cmp al,32      ;Space, place X,O on Board
    jmp BoardEdge

    moveRight:
        mov al,[xPos]   
        cmp al,15
        jz BoardEdge
        
        add [xPos],1
        jmp BoardEdge
        
    moveLeft:
        mov al,[xPos]       
        cmp al,2
        jz BoardEdge
        
        sub [xPos],1
        jmp BoardEdge
        
    moveUp:
        mov al,[yPos]   
        cmp al,1
        jz BoardEdge
        
        sub [yPos],1
        jmp BoardEdge
        
    moveDown:
        mov al,[yPos]   
        cmp al,5
        jz BoardEdge
        
        add [yPos],1
        
        BoardEdge:
        
    ret
BoardAction Endp

    
game_over: 

mov     dx, offset msg2
mov     ah, 9 
int     21h

       mov ax, 4c00h
        int 21h

相关问题