Skip to content

Instantly share code, notes, and snippets.

@remexre
Created October 18, 2013 15:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save remexre/7042910 to your computer and use it in GitHub Desktop.
Save remexre/7042910 to your computer and use it in GitHub Desktop.
Simple x86 Assembly (Intel syntax) minesweeper.
[section .text]
GLOBAL _start
tiles:
.unknown equ '.'
.empty equ ' '
.mine equ '!'
_start:
call initBoard
mov byte [gameOver], FALSE
.mainLoop:
call printBoard
call getCoords
call uncoverTile
cmp byte [gameOver], FALSE
je .mainLoop
call printBoard
mov rax, sys_write
mov rbx, STDOUT
mov rcx, strings.gameOver
mov rdx, gameOverLen
int 0x80
mov rax, sys_exit
xor rbx, rbx
int 0x80
ret
initBoard:
mov rcx, 100
.put:
mov byte [board+rcx-1], tiles.unknown
dec rcx
cmp rcx, 0
ja .put
mov rax, sys_time
mov rbx, mines
int 0x80
xor rcx, rcx
.maskLoop:
cmp byte [mines+rcx], 10
jb .maskLoopEnd
xor rax, rax
mov al, byte [mines+rcx]
mov rbx, 10
div bl
mov byte [mines+rcx], ah
.maskLoopEnd:
inc rcx
cmp rcx, 20 ; NOT hex
jb .maskLoop
ret
printBoard:
push board
.innerLoop:
mov rax, sys_write
mov rbx, STDOUT
mov rcx, [rsp]
mov rdx, 10
int 0x80
.newline:
mov rax, sys_write
mov rbx, STDOUT
mov rcx, strings.newLine
mov rdx, newLineLen
int 0x80
pop rcx
add rcx, 10
push rcx
cmp rcx, board+100
jb .innerLoop
add rsp, 8 ; pop to /dev/null
ret
getCoords:
.x:
mov rax, sys_write
mov rbx, STDOUT
mov rcx, strings.enterX
mov rdx, enterXLen
int 0x80
mov rax, sys_read
mov rbx, STDIN
mov rcx, buffer
mov rdx, bufferLen
int 0x80
mov al, byte [buffer]
sub al, 0x30 ; ASCII to "raw"
cmp al, 0x09
ja .x ; Unsigned jump will also nix a negative.
mov byte [coords.x], al
.y:
mov rax, sys_write
mov rbx, STDOUT
mov rcx, strings.enterY
mov rdx, enterYLen
int 0x80
mov rax, sys_read
mov rbx, STDIN
mov rcx, buffer
mov rdx, bufferLen
int 0x80
mov al, byte [buffer]
sub al, 0x30
cmp al, 0x09
ja .y
mov byte [coords.y], al
ret
uncoverTile:
call isMine
je .mine
.empty:
xor rax, rax
mov ah, byte [coords.x]
mov al, 10
imul ah
add al, byte [coords.y]
mov byte [board+rax], tiles.empty
ret
.mine:
xor rax, rax
mov ah, byte [coords.x]
mov al, 10
imul ah
add al, byte [coords.y]
mov byte [board+rax], tiles.mine
mov byte [gameOver], TRUE
ret
isMine: ;; TODO
xor rax, rax
xor rcx, rcx
.loopX:
; if(mines[rcx] == coords['x']) goto .checkY
mov al, byte [coords.x]
cmp byte [mines+rcx], al
je .checkY
add rcx, 2
cmp rcx, 20
jb .loopX
jmp .exit
.checkY:
add rcx, 2
mov al, byte [coords.y]
cmp byte [mines+rcx-1], al
jne .loopX
xor rax, rax
cmp rax, 0x00 ; Set zero flag
ret
.exit:
xor rax, rax
cmp rax, 0x01 ; Clear zero flag
ret
[section .data]
strings:
.enterX: db "Enter the x (0-9): "
enterXLen equ $ - strings.enterX
.enterY: db "Enter the y (0-9): "
enterYLen equ $ - strings.enterY
.gameOver: db 0x1B, "[1;31mGAME OVER", 0x1B, "[0m", 0x0A
gameOverLen equ $ - strings.gameOver
.newLine: db 0x0A
newLineLen equ $ - strings.newLine
[section .bss]
board: resb 100
buffer: resb bufferLen
bufferLen equ 0xFF
coords:
.x: resb 0x01
.y: resb 0x01
gameOver: resb 0x01
rngVal: resq 0x01
mines: resb 20
sys_exit equ 0x01
sys_read equ 0x03
sys_write equ 0x04
sys_time equ 0x0D
STDIN equ 0x00
STDOUT equ 0x01
STDERR equ 0x02
FALSE equ 0x00
TRUE equ 0x01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment