1. 程式人生 > >無系統 nasm彙編貪吃蛇demo草稿

無系統 nasm彙編貪吃蛇demo草稿

開發系統centos 6.5 64位,利用系統時鐘中斷和鍵盤中斷

原始碼檔案snake.s

org 7c00h

global start
start:

    jmp entry
#    db 0x00
#    db "helloOSX"
#    dw  512
#    db  1
#    dw  1
#    db  2
#    dw  224
#    dw  2880
#    db  0xf0
#    dw  9
#    dw  18
#    dw  2
#    dd  0
#    dd  2880
#    db  0,0,0x29

#    dd  0xffffffff
#    db  "myosudisk  "
#    db  "fat12   "
#    times 18 db 0

keyboard_interrupt:  
    in  al,0x60
    and al,0x80

	mov ah,al	
	cmp ah,byte [forbiden]
	jz keyboard_interrupt_exit 
	
	cmp ah,0x50
	jz gotkey
	cmp ah,0x4b
	jz gotkey
	cmp ah,0x4d
	jz gotkey
	cmp ah,0x48
	jnz keyboard_interrupt_exit
gotkey:
	mov byte[dir],ah

keyboard_interrupt_exit:
	iret 
	
handler:
	nop
	mov al,byte [counter]
	inc al
	mov byte [counter],al
	cmp al,10
	jnz handler_exit
	mov al,0
	mov byte [counter],al	

premove:
	mov bx,word [snake]
	mov ah,byte [dir]
	cmp ah,0x48
	jz up
	cmp ah,0x50
	jz down
	cmp ah,0x4b
	jz left
	cmp ah,0x4d
	jz right
	jmp move  
up:
	mov byte [forbiden],0x50
	dec bh
	jmp move
down:
	mov byte [forbiden],0x48
	inc	bh
	jmp move
left:
	mov byte [forbiden],0x4d
	dec bl
	jmp move
right:
	mov byte [forbiden],0x4b
	inc bl
move:
	call deadcheck
	mov di,snake
	add di,word [snakelen]
	add di,word [snakelen]
	sub di,2
moveloop:
	sub di,2
	mov ax,word [es:di]
	add di,2
	mov word [es:di],ax
	sub di,2	
	cmp di,snake
	jnz moveloop

	mov word [snake],bx
	call clear
	call putsnake
handler_exit:
	mov al,20h
	out 20h,al
	iret	

setuptimer:
	mov ax,0 ;在8*4記憶體地址處註冊中斷處理程式的入口地址
	mov ds,ax
	mov bx,32
	mov word [bx],handler-$$
	mov word [bx+2],07c0h
	int 8h

;	mov bx,36
;	mov word [bx],keyboard_interrupt-$$
;	mov word [bx+2],keyboard_interrupt-$$
;	int 8h

	sti
	ret
	
entry:
	nop
	mov ax,cs
	mov es,ax

	; set video mode
	mov ah,0
	mov al,3
	int 10h
	call clear
	call gamestart
	call getchar
	call clear
	call putsnake	
	
	call setuptimer

loop:
	jmp $

putchar:
	push bp
	mov bp,sp
	push ax
	push bx
	push cx
	push dx

	mov AH,02h
	mov BH,0h
	mov dx,[bp+4]
	int 10h
	
	mov AH,09h
	mov AL,03h
	mov BH,0
	;mov BL,77h
	mov bx,13
	mov bh,0
	mov CX,1
	int 10h
	
	pop dx
	pop cx
	pop bx
	pop ax
	mov sp,bp
	pop bp
	ret

putsnake:
	push ax
	push cx
	push di

	mov cx,word [snakelen]
	mov di,snake
putloop:
	mov ax,[es:di]
	push ax
	call putchar
	add sp,2
	add di,2
	dec cx
	jnz putloop

	pop di	
	pop cx
	pop ax
	ret

getchar:
    mov ah, 1  
    int 16h  
    jz getchar_clear_read ; ///< 鍵盤緩衝區都空了, 可以轉"讀鍵盤輸入"  
  
    mov ah, 0  
    int 16h  
    jmp getchar ; ///< 繼續清鍵盤緩衝區  
  
getchar_clear_read:   
    mov ah, 1  
    int 16h  
    jz getchar_clear_read ; ///< 如果沒有鍵盤輸入,繼續死等鍵盤輸入  
  
    mov ah, 0 ; ///< al是鍵盤輸入  
    int 16h  
    ret
 
clear:
	push ax
	push bx
	push cx
	push dx
	mov bh,7
	mov ah,6
	mov al,0
	mov ch,0
	mov cl,0
	mov dh,24
	mov dl,79
	int 10h
	pop dx
	pop cx
	pop bx
	pop ax
	ret

gamestart:
	mov si,bp
	mov bp,startstr		;es:bp 指向的內容就是我們要顯示的字串地址了
	mov cx,word [startlen]		;顯示的字串長度
	mov dh,12			;顯示的行號
	mov dl,36			;顯示的列號
	mov bh,0			;顯示的頁數
	mov al,1			;顯示的是串結構
	mov bl,0ch			;顯示的字元屬性
	mov ah,13h			;明確呼叫13h子程式
	int 10h
	mov bp,si
	ret

gameover:
	mov bp,endstr		;es:bp 指向的內容就是我們要顯示的字串地址了
	mov cx,word [endlen]			;顯示的字串長度
	mov dh,12			;顯示的行號
	mov dl,36			;顯示的列號
	mov bh,0			;顯示的頁數
	mov al,1			;顯示的是串結構
	mov bl,0ch			;顯示的字元屬性
	mov ah,13h			;明確呼叫13h子程式
	int 10h
	jmp $

deadcheck:
	cmp bl,79
	JG gameover
	cmp bh,24	
	jg gameover
	cmp bl,0
	jz gameover
	cmp bh,0
	jz gameover
	ret



counter: db 0
dir:	db 0x4d
forbiden: db 0x4b	
startstr: db "press s to start"
startlen: dw $-startstr
endstr: db	"Game Over!"
endlen dw	$-endstr
snake: dw 0509h,0508h,0507h,0506h,0505h
snakelen: dw 5 

times 510-($-$$) db 0
dw 0xaa55


makefile

all:
	nasm -o snake.o snake.s
	dd if=./snake.o of=snake.img bs=512 count=1
	dd if=/dev/zero of=snake.img seek=1 count=2879
	sz snake.img

linux:
	nasm -f elf64 -g -F stabs -o snake.o snake.s -l snake.l
	ld -o snake snake.o
clean:
	rm -f *.o *.img