回 帖 发 新 帖 刷新版面

主题:[原创]汇编版贪吃蛇

这个在Emu8086v3.07下调试通过
; This is the snake game...
;
; It's better to set the
; "step delay" to "0" before
; running, it requires fast
; processing.
;
; You can control the snake
; using arrow keys on your
; keyboard.
;
; All other keys will stop
; the snake.
;
; Press ESC to exit.


#make_COM#

ORG     100h

; jump over data section:
JMP     start

; ------ DATA section ------

s_size  EQU     7

; the snake coordinates
; (from head to tail)
; low byte is left, high byte
; is top - [top, left]
snake DW s_size DUP(0)

tail    DW      ?

; direction constants
;          (BIOS key codes):
LEFT    EQU     4Bh
RIGHT   EQU     4Dh
UP      EQU     48h
DOWN    EQU     50h

; current snake direction:
cur_dir DB      RIGHT

wait_time DW    0

; ------ CODE section ------

start:

CALL SayThis
DB "==== HOW TO PLAY ====", 13, 10
DB "It's better to set the", 13, 10
DB '"step delay" to "0" before', 13, 10
DB "running, it requires fast", 13, 10
DB "processing.", 13, 10, 13, 10

DB "You can control the snake", 13, 10
DB "using arrow keys on your", 13, 10
DB "keyboard.", 13, 10, 13, 10

DB "All other keys will stop", 13, 10
DB "the snake.", 13, 10, 13, 10

DB "Press ESC to exit.", 13, 10
DB "====================", 13, 10, 13, 10
DB "Press any key to start...", 0


; wait for any key:
MOV AH, 00h
INT 16h


; hide text cursor:
; (emulator shows
; text cursor only when
; it wait for input, so
; this is optional)
MOV     AH, 1
MOV     CH, 2Bh
MOV     CL, 0Bh
INT     10h


game_loop:

; === select first video page
MOV     AL, 0  ; page number.
MOV     AH, 05h
INT     10h

; === show new head:
MOV     DX, snake[0]

; set cursor at DL,DH
MOV     AH, 02h
INT     10h

; print '*' at the location:
MOV     AL, '*'
MOV     AH, 09h
MOV     BL, 0Eh ; attribute.
MOV     CX, 1   ; single char.
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 location:
MOV     AL, ' '
MOV     AH, 09h
MOV     BL, 0Eh ; attribute.
MOV     CX, 1   ; single char.
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

; ------ functions section ------

; This procedure creates the
; animation by moving all snake
; body parts one step to tail,
; the old tail goes away:
; [Last part (tail)]-> goes away
; [Part i] -> [Part i+1]
; ....

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
  MOV   b.snake[0], AL  ; return to right.
  JMP   stop_move

move_right:
  MOV   AL, b.snake[0]
  INC   AL
  MOV   b.snake[0], AL
  CMP   AL, ES:[4Ah]    ; col number.   
  JB    stop_move
  MOV   b.snake[0], 0   ; 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.
  MOV   b.snake[1], AL  ; 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
  MOV   b.snake[1], 0   ; return to top.
  JMP   stop_move

stop_move:
  RET
move_snake ENDP



; Procedure to print a null terminated
; string at current cursor position.
; The ZERO TERMINATED string should be
; defined just after the CALL.
; For example:
;
; CALL SayThis
; db 'Hello World!', 0
;
; Address of string is stored in the Stack
; as return address.
; Procedure updates value in the Stack to
; make return after string definition.
SayThis PROC NEAR

MOV     CS:temp1, SI  ; re-store SI register.

POP     SI            ; get return address (IP).

PUSH    AX            ; store AX register.

next_char:      
        MOV     AL, CS:[SI]
        INC     SI            ; next byte.
        CMP     AL, 0
        JZ      printed        
        MOV     AH, 0Eh       ; teletype function.
        INT     10h
        JMP     next_char     ; loop.
printed:

POP     AX            ; re-store AX register.

; SI should point to next command after
; the CALL instruction and string definition:
PUSH    SI            ; save new return address into the Stack.

MOV     SI, CS:temp1  ; re-store SI register.

RET
temp1  DW  ?    ; variable to store original value of SI register.
SayThis ENDP



END

回复列表 (共9个回复)

沙发

能编写这样的程序,可谓高手也

板凳

和Emu8086样例程序里面的snake.asm一模一样

3 楼

4 楼

EMU8086是什么啊……为什么我编译通不过??!!

5 楼

它是一个WIN32的汇编语言编译器。你可以在网上搜一搜。就会知道啦。

6 楼

想要简短的我发
我也编了一个

7 楼

6楼得发一个来看看。。。。。

8 楼

可否在masm5.0里编译呢,楼主?

9 楼

这个好象不可以。

我来回复

您尚未登录,请登录后再回复。点此登录或注册