⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snake.asm

📁 一个简单的贪食蛇的汇编语言的校程序
💻 ASM
字号:
;*****************************snake************************************
TRUE = 1
COLOR = 66                                ;snake的颜色(0-255)
;**********************************************************************
;退出并还原用户的显示方式
exit macro 
    push ax       
    mov ah, 0h                            ;bios功能调用
    mov al, vdMode
    int 10h
    mov ax, 4c00h
    int 21h
    pop ax
    endm
;*********************************************************************
    .model small    
;*********************************************************************    
    .data
top     db 42 dup(-1)    
table   db 25 DUP(-1, 40 DUP(0), -1)
bottom  db 42 dup(-1)
row     dw 0  
column  dw 0
head    dw 675                            ;指向snake头部
tail    dw 673                            ;指向snake尾部
vdMode  db 0                              ;保存用户的显示方式
bWait   db 20                             ;时间延迟 = 0.05s的倍数
key     db 4dh                            ;保存从键盘输入的字符的扫描码
stay    db 0                              ;暂停标记
bkColor db 0                              ;保存背景颜色
prompt  db 0ah, 0dh, "****************************************",
           0ah, 0dh, "*** pause: space                     ***", 
           0ah, 0dh, "*** exit: q(Q)/ESC                   ***", 
           0ah, 0dh, "****************************************", 
           0ah, 0dh, "Please enter A(easy)or B(common)or C(crazy): $"                      
;*********************************************************************
    .code
main proc far
    mov ax, @data
    mov ds, ax
    
slt:
    mov ah, 09h
    mov dx, offset prompt
    int 21h
    mov ah, 01h
    int 21h
    .if (al=='A')||(al=='a')
        mov bWait, byte ptr 20            ;延迟1s
    .elseif (al=='B')||(al=='b')
        mov bWait, byte ptr 10            ;延迟0.5s
    .elseif (al=='C')||(al=='c')          
        mov bWait, byte ptr 5             ;延迟0.25s
    .else
        jmp slt
    .endif        
    
    call initial 
    
    .while TRUE
next:   
        mov ah, 0bh                       ;DOS功能调用,检查是否按下键盘
        int 21h
        .if al 
             call getKey
        .endif     
        .break .if (key==10h)||(key==01h) ;退出
        .if stay                          ;暂停
            jmp next
        .endif     
        call setSnk
        call waitf                        ;延迟bWait×0.5s
    .endw
  
    exit
main endp
;*********************************************************************
;从键盘读取字符,并保存扫描码在key
getKey proc near uses ax bx
    mov ah, 0h                            ;bios功能调用,读取键盘
    int 16h
    
    mov al, key
    .if ah == 48h                         ;上方向键
        .if al != 50h                     
            mov key, ah
        .endif 
    .elseif ah == 4bh                     ;左方向键 
        .if al !=4dh
            mov key, ah
        .endif            
    .elseif ah == 4dh                     ;右方向键 
        .if al != 4bh
            mov key, ah
        .endif
    .elseif ah == 50h
        .if al != 48h
            mov key, ah
        .endif
    .elseif (ah==10h)||(ah==01h)          ;q(Q)或ESC退出                
       mov key, ah
    .elseif ah == 39h                     ;space暂停或终止暂停
        .if stay == 1
            mov stay, byte ptr 0
        .else
            mov stay, byte ptr 1
        .endif      
    .endif       
    
    ret
getKey endp
;*********************************************************************
;产生时间延迟 bWait × 0.05s
waitf proc near uses cx ax bx
    mov bl, bWait
wait1: 
    mov cx, 3314
wait2:
    in al, 61h
    and al, 10h
    cmp al, ah
    je wait2
    mov ah, al    
    loop wait2
    dec bl
    cmp bl, 0
    ja wait1
    ret
waitf endp
;*********************************************************************
;在数组(row, column)映射到的在屏幕上的区域画宽为8个像素的方块,al=方块的颜色
box proc near c uses ax bx cx dx si di
    mov dx, row
    mov bx, column
    mov cl, 3
    shl dx, cl
    shl bx, cl
    mov cx, bx
    mov column, cx
    
    mov si, 8
    mov ah, 0ch                           ;bios功能调用,写像素
    mov bh, 0
box1:
    mov di, 8
box2:
    int 10h
    inc cx
    dec di
    cmp di, 0
    ja box2
    inc dx 
    mov cx, column 
    dec si
    cmp si,0      
    ja box1
    
    ret
box endp
;*********************************************************************
;初始化屏幕
initial proc near c uses ax bx cx dx
    mov ah, 0fh                           ;bios功能调用,取用户显示方式并保存
    int 10h
    mov vdMode, al
    
    mov ah, 0                             ;bios功能调用,设置显示方式    
    mov al, 13                            ;320×200 256色图形 
    int 10h
    
    mov ah, 6                             ;bios功能调用,清除屏幕
    mov al, 0
    mov bh, 255
    mov cx, 0
    mov dx, 184fh
    int 10h
    
    mov ah, 0dh                           ;bios功能调用,读像素的颜色
    mov bh, 0
    mov dx, 10
    mov cx, 10
    int 10h
    mov bkColor, al
    
    mov al, COLOR
    mov bx, 673                           ;42×14 +1
    mov table[bx],byte ptr 3
    mov row, word ptr 16
    mov column, word ptr 0
    call box
    inc bx                                ;42×14 +2
    mov table[bx], byte ptr 2
    mov column, word ptr 1
    call box
    inc bx                                ;42×14 +3
    mov table[bx], byte ptr 1
    mov column, word ptr 2
    call box
    
    call rand
    ret
initial endp    
;*********************************************************************
;随机地产生一个方块
rand proc near uses ax bx dx di si
start_Rand:
    mov ah, 0h                            ;bios功能调用,读系统时钟
    int 1ah                               ;随机产生行
    xor ah, ah
    mov al, dl
    mov dl, 25
    div dl
    mov al, ah
    xor ah, ah    
    mov di, ax                             ;0~24
    
    mov ah, 0h                            ;随机产生列
    int 1ah
    xor ah, ah
    mov al, dl
    mov dl, 40
    div dl
    mov al, ah
    xor ah, ah
    mov si, ax
    
    mov ax, 42
    mul di
    mov bx, ax
    add bx, si
    inc bx
    
    cmp table[bx], 0
    jne start_Rand
    mov table[bx], 200
    mov row, di
    mov column, si
    mov al, COLOR
    call box
    ret
rand endp
;*********************************************************************
;当snake游动时,重新设置
setSnk proc near

    mov bx, head
    .if  key == 48h                       ;上方向键
        sub bx, 42     
    .elseif key == 4bh                    ;左方向键
        sub bx, 1
    .elseif key == 4dh                    ;右方向键
        add bx, 1    
    .elseif key == 50h                    ;下方向键
        add bx, 42
    .endif  
 
    .if (table[bx]==-1)||((table[bx]>=2)&&(table[bx]<=150) )
        mov key, 01h                      ;退出
        ret
    .elseif table[bx] == 0
        call setBody
    .elseif table[bx] == 200              ;吞食方块
        call setEat
        call rand
    .endif 
    
    ret
setSnk endp 
;*********************************************************************
;snake游动(不吞食方块)
setBody proc near uses ax bx cx dx
    .if key == 48h   
        sub head, 42
    .elseif key == 4bh                    ;左方向键
        sub head, 1
    .elseif key == 4dh                    ;右方向键
        add head, 1 
    .elseif key == 50h                    ;下方向键   
        add head, 42
    .endif
    mov bx, head
    mov table[bx], byte ptr 1
    mov ax, bx
    mov bl, 42
    div bl
    xor bh, bh
    mov bl, al
    mov row, bx
    dec ah
    mov bl, ah
    mov column, bx 
    mov al, COLOR
    call box
    
    mov bx, tail
    mov cl, table[bx]                     ;保存tail指向的值
    mov table[bx], byte ptr 0
    mov ax, bx
    mov bl, 42
    div bl
    xor bh, bh
    mov bl, al
    mov row, bx
    dec ah
    mov bl, ah
    mov column, bx
    mov al, bkColor
    call box
     
    dec cl
    mov bx, tail
    sub bx, 42
    .if cl == table[bx]     
        inc table[bx]
        mov tail, bx
        jmp endTail
    .endif
    mov bx, tail
    dec bx
    .if cl == table[bx]
        inc table[bx]
        mov tail, bx    
        jmp endTail
    .endif
    mov bx, tail
    inc bx
    .if cl == table[bx]
        inc table[bx]
        mov tail, bx
        jmp endTail
    .endif
    mov bx, tail
    add bx, 42
    .if cl == table[bx]
        inc table[bx]
        mov tail, bx
    .endif

endTail:         
    xor ch, ch  
    dec cl
    mov dx, tail      
nextSet:
    mov bx, dx
    sub bx, 42
    .if cl == table[bx]
        inc table[bx]
        mov dx, bx
        jmp set1
    .endif
    mov bx, dx
    dec bx
    .if cl == table[bx]
        inc table[bx]
        mov dx, bx
        jmp set1
    .endif    
    mov bx, dx
    inc bx
    .if cl == table[bx]
        inc table[bx]
        mov dx, bx
        jmp set1
    .endif  
    mov bx, dx
    add bx, 42
    .if cl == table[bx]
        inc table[bx]
        mov dx, bx
        jmp set1
    .endif    
set1:    
    loop nextSet    
    
    ret
setBody endp
;*********************************************************************
setEat proc near uses ax bx cx dx
    mov bx, tail
    xor ch, ch
    mov cl, table[bx]
    mov bx, head
eatNext:
    inc table[bx]
    mov ah, table[bx]
    mov dx, bx
    
    sub bx, 42
    .if ah == table[bx] 
        mov dx, bx
        jmp eat
    .endif
    mov bx, dx
    sub bx, 1
    .if ah == table[bx]
        mov dx, bx
        jmp eat
    .endif 
    mov bx, dx
    add bx, 1
    .if ah == table[bx]
        mov dx, bx
        jmp eat
    .endif 
    mov bx, dx
    add bx, 42
    .if ah == table[bx]
        mov dx, bx
        jmp eat
    .endif               
    
eat:    
    loop eatNext    
    
    .if key == 48h
        sub head, 42
    .elseif key == 4bh
        dec head
    .elseif key == 4dh
        inc head
    .elseif key == 50h
        add head, 42       
    .endif
    
    mov bx, head
    mov table[bx], 1    
    ret
setEat endp
;*********************************************************************
    end main    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -