Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1128767ea3 |
@ -1,5 +1,5 @@
|
|||||||
echo ">>> Compiling ASM code..."
|
echo ">>> Compiling ASM code..."
|
||||||
nasm -f macho64 -g -o ./bin/obj/main.o ./src/main.asm
|
nasm -f macho64 -o ./bin/obj/main.o ./src/main.asm
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo " >> Error: Assembly failed."
|
echo " >> Error: Assembly failed."
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@ -1,76 +0,0 @@
|
|||||||
; returns the user input in r15
|
|
||||||
; 0x01 = up
|
|
||||||
; 0x02 = left
|
|
||||||
; 0x03 = down
|
|
||||||
; 0x04 = right
|
|
||||||
; 0xDEAD = no valid key pressed
|
|
||||||
read_user_input:
|
|
||||||
; Read user input for the game
|
|
||||||
; Read AWSD keys (basically, read a single byte)
|
|
||||||
|
|
||||||
; Ensure symmetric register saving
|
|
||||||
push rax ; added missing push for symmetry
|
|
||||||
push rbx
|
|
||||||
push rcx
|
|
||||||
push rdx
|
|
||||||
|
|
||||||
push rsi
|
|
||||||
push rdi
|
|
||||||
|
|
||||||
xor r15, r15 ; Clear r15 to indicate no valid key pressed
|
|
||||||
|
|
||||||
; changed: use read syscall number 0x2000003
|
|
||||||
mov rax, 0x2000003
|
|
||||||
mov rdi, 0
|
|
||||||
lea rsi, [rsp] ; Read into stack
|
|
||||||
mov rdx, 1
|
|
||||||
syscall
|
|
||||||
|
|
||||||
; Check for W key
|
|
||||||
cmp byte [rsp], 0x77
|
|
||||||
je up_key
|
|
||||||
; Check for A key
|
|
||||||
cmp byte [rsp], 0x61
|
|
||||||
je left_key
|
|
||||||
; Check for S key
|
|
||||||
cmp byte [rsp], 0x73
|
|
||||||
je down_key
|
|
||||||
; Check for D key
|
|
||||||
cmp byte [rsp], 0x64
|
|
||||||
je right_key
|
|
||||||
|
|
||||||
; Check for e key
|
|
||||||
cmp byte [rsp], 0x65
|
|
||||||
je unburry_key
|
|
||||||
|
|
||||||
mov r15, 0xDEAD ; Debug: no valid key pressed
|
|
||||||
jmp exit_user_with_no_input
|
|
||||||
|
|
||||||
up_key:
|
|
||||||
mov r15, 0x01 ; Debug: up key pressed
|
|
||||||
jmp exit_user_with_no_input
|
|
||||||
|
|
||||||
left_key:
|
|
||||||
mov r15, 0x02 ; Debug: left key pressed
|
|
||||||
jmp exit_user_with_no_input
|
|
||||||
|
|
||||||
down_key:
|
|
||||||
mov r15, 0x03 ; Debug: down key pressed
|
|
||||||
jmp exit_user_with_no_input
|
|
||||||
|
|
||||||
right_key:
|
|
||||||
mov r15, 0x04 ; Debug: right key pressed
|
|
||||||
jmp exit_user_with_no_input
|
|
||||||
|
|
||||||
unburry_key:
|
|
||||||
mov r15, 0x05 ; Debug: unburry key pressed
|
|
||||||
|
|
||||||
exit_user_with_no_input:
|
|
||||||
; Restore registers
|
|
||||||
pop rdi
|
|
||||||
pop rsi
|
|
||||||
pop rdx
|
|
||||||
pop rcx
|
|
||||||
pop rbx
|
|
||||||
pop rax
|
|
||||||
ret
|
|
||||||
245
src/main.asm
245
src/main.asm
@ -14,37 +14,42 @@ section .data
|
|||||||
user_input times 3 db 0
|
user_input times 3 db 0
|
||||||
user_input_len equ $ - user_input
|
user_input_len equ $ - user_input
|
||||||
|
|
||||||
|
|
||||||
newline db 0xA, 0
|
newline db 0xA, 0
|
||||||
newline_len equ $ - newline
|
newline_len equ $ - newline
|
||||||
digit_buffer db 0
|
digit_buffer db 0
|
||||||
|
|
||||||
first_move db 0
|
|
||||||
|
|
||||||
section .bss
|
section .bss
|
||||||
board resb 100
|
board resb 100
|
||||||
; termios resb 20 ; Reserve space for termios structure
|
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
global _main
|
global _main
|
||||||
|
|
||||||
_main:
|
_main:
|
||||||
; Initialize the board with mines and empty tiles
|
; Fill the board with 0s and 1s
|
||||||
xor rax, rax
|
xor r10, r10 ; Counter
|
||||||
|
lea r11, [rel board] ; Load address of board
|
||||||
|
|
||||||
; Set up user location
|
mov rcx, 100 ; Loop 100 times
|
||||||
mov byte [rel user_location_pos], 0
|
fill_loop:
|
||||||
|
rdrand rax
|
||||||
|
and rax, 15 ; Reduce probability of mine (1 in 16 chance)
|
||||||
|
cmp rax, 1
|
||||||
|
sete al ; Set al to 1 if rax == 1, otherwise 0
|
||||||
|
mov [r11 + r10], al ; Store at board[r10]
|
||||||
|
inc r10
|
||||||
|
loop fill_loop
|
||||||
|
|
||||||
; Print the board
|
; Print the board
|
||||||
xor r10, r10 ; Reset counter before refill
|
xor r10, r10 ; Reset counter
|
||||||
|
|
||||||
print_loop:
|
print_loop:
|
||||||
xor rcx , rcx ; Reset mine count
|
xor rcx , rcx ; Reset mine count
|
||||||
lea r11, [rel board]
|
lea r11, [rel board]
|
||||||
movzx rax, byte [r11 + r10] ; Load board[r10]
|
movzx rax, byte [r11 + r10] ; Load board[r10]
|
||||||
|
|
||||||
; Print user location (load byte with zero-extension)
|
; Print user location
|
||||||
movzx rbx, byte [rel user_location_pos]
|
cmp r10, [rel user_location_pos]
|
||||||
cmp r10, rbx
|
|
||||||
jne not_user_location
|
jne not_user_location
|
||||||
lea r8, [rel user_location]
|
lea r8, [rel user_location]
|
||||||
mov r9, tile_len
|
mov r9, tile_len
|
||||||
@ -107,119 +112,115 @@ no_newline:
|
|||||||
cmp r10, 100
|
cmp r10, 100
|
||||||
jb print_loop
|
jb print_loop
|
||||||
|
|
||||||
; Small bracket to be able to distinguish between first move and refill
|
; Read arrow keys
|
||||||
lea r8, [rel newline]
|
|
||||||
mov r9, newline_len
|
|
||||||
call print_String
|
|
||||||
call print_String
|
|
||||||
|
|
||||||
xor r15, r15
|
|
||||||
; Read user input
|
|
||||||
call read_user_input
|
|
||||||
|
|
||||||
cmp byte [rel first_move], 0 ; Compare memory content of first_move
|
|
||||||
je not_first_move
|
|
||||||
; Instead of resetting and jumping to fill_loop, call fill_board from ui.asm
|
|
||||||
call fill_board
|
|
||||||
jmp print_loop
|
|
||||||
|
|
||||||
not_first_move:
|
|
||||||
|
|
||||||
; Check if user pressed a valid key
|
|
||||||
cmp r15, 0xDEAD
|
|
||||||
je invalid_key
|
|
||||||
|
|
||||||
cmp r15, 0x01
|
|
||||||
je move_up
|
|
||||||
|
|
||||||
cmp r15, 0x02
|
|
||||||
je move_left
|
|
||||||
|
|
||||||
cmp r15, 0x03
|
|
||||||
je move_down
|
|
||||||
|
|
||||||
cmp r15, 0x04
|
|
||||||
je move_right
|
|
||||||
|
|
||||||
cmp r15, 0x05
|
|
||||||
je unburry
|
|
||||||
|
|
||||||
jmp invalid_key
|
|
||||||
move_up:
|
|
||||||
; Move up
|
|
||||||
lea r8, [rel user_location]
|
|
||||||
mov r9, tile_len
|
|
||||||
call print_String
|
|
||||||
|
|
||||||
; Update user location safely (read one byte)
|
|
||||||
movzx rax, byte [rel user_location_pos]
|
|
||||||
sub rax, 10
|
|
||||||
mov [rel user_location_pos], al
|
|
||||||
|
|
||||||
; Print the board again
|
|
||||||
|
|
||||||
xor r10, r10 ; Reset counter before refill
|
|
||||||
jmp print_loop
|
|
||||||
move_left:
|
|
||||||
; Move left
|
|
||||||
lea r8, [rel user_location]
|
|
||||||
mov r9, tile_len
|
|
||||||
call print_String
|
|
||||||
|
|
||||||
; Update user location safely (read one byte)
|
|
||||||
movzx rax, byte [rel user_location_pos]
|
|
||||||
sub rax, 1
|
|
||||||
mov [rel user_location_pos], al
|
|
||||||
|
|
||||||
; Print the board again
|
|
||||||
|
|
||||||
xor r10, r10 ; Reset counter before refill
|
|
||||||
jmp print_loop
|
|
||||||
|
|
||||||
move_down:
|
|
||||||
; Move down
|
|
||||||
lea r8, [rel user_location]
|
|
||||||
mov r9, tile_len
|
|
||||||
call print_String
|
|
||||||
|
|
||||||
; Update user location safely (read one byte)
|
|
||||||
movzx rax, byte [rel user_location_pos]
|
|
||||||
add rax, 10
|
|
||||||
mov [rel user_location_pos], al
|
|
||||||
|
|
||||||
; Print the board again
|
|
||||||
|
|
||||||
xor r10, r10 ; Reset counter before refill
|
|
||||||
jmp print_loop
|
|
||||||
move_right:
|
|
||||||
; Move right
|
|
||||||
lea r8, [rel user_location]
|
|
||||||
mov r9, tile_len
|
|
||||||
call print_String
|
|
||||||
|
|
||||||
; Update user location safely (read one byte)
|
|
||||||
movzx rax, byte [rel user_location_pos]
|
|
||||||
add rax, 1
|
|
||||||
mov [rel user_location_pos], al
|
|
||||||
|
|
||||||
; Print the board again
|
|
||||||
|
|
||||||
xor r10, r10 ; Reset counter before refill
|
|
||||||
jmp print_loop
|
|
||||||
|
|
||||||
unburry:
|
|
||||||
; Unburry the tile: set first move flag and refill board
|
|
||||||
mov byte [rel first_move], 1
|
|
||||||
call fill_board
|
|
||||||
jmp print_loop
|
|
||||||
|
|
||||||
; Invalid key pressed
|
|
||||||
invalid_key:
|
|
||||||
|
|
||||||
; Exit
|
; Exit
|
||||||
mov rax, 0x2000001
|
mov rax, 0x2000001
|
||||||
xor rdi, rdi
|
xor rdi, rdi
|
||||||
syscall
|
syscall
|
||||||
|
|
||||||
%include "./src/io/io.asm"
|
; r8 = string
|
||||||
%include "./src/ui/ui.asm"
|
; r9 = length
|
||||||
|
print_String:
|
||||||
|
mov rax, 0x2000004
|
||||||
|
mov rdi, 1
|
||||||
|
mov rsi, r8
|
||||||
|
mov rdx, r9
|
||||||
|
syscall
|
||||||
|
ret
|
||||||
|
|
||||||
|
; r10 = current tile index
|
||||||
|
; r11 = board
|
||||||
|
; rdx = mine count
|
||||||
|
; r8 = offset
|
||||||
|
count_adjacent_mines:
|
||||||
|
xor rdx, rdx
|
||||||
|
mov r8, 0
|
||||||
|
|
||||||
|
; Check top left
|
||||||
|
mov rax, r10
|
||||||
|
sub rax, 11
|
||||||
|
cmp rax, 0
|
||||||
|
jl .skip_top_left
|
||||||
|
movzx rax, byte [r11 + rax]
|
||||||
|
cmp rax, 1
|
||||||
|
sete al
|
||||||
|
add dl, al
|
||||||
|
.skip_top_left:
|
||||||
|
|
||||||
|
; Check top
|
||||||
|
mov rax, r10
|
||||||
|
sub rax, 10
|
||||||
|
cmp rax, 0
|
||||||
|
jl .skip_top
|
||||||
|
movzx rax, byte [r11 + rax]
|
||||||
|
cmp rax, 1
|
||||||
|
sete al
|
||||||
|
add dl, al
|
||||||
|
.skip_top:
|
||||||
|
|
||||||
|
; Check top right
|
||||||
|
mov rax, r10
|
||||||
|
sub rax, 9
|
||||||
|
cmp rax, 0
|
||||||
|
jl .skip_top_right
|
||||||
|
movzx rax, byte [r11 + rax]
|
||||||
|
cmp rax, 1
|
||||||
|
sete al
|
||||||
|
add dl, al
|
||||||
|
.skip_top_right:
|
||||||
|
|
||||||
|
; Check left
|
||||||
|
mov rax, r10
|
||||||
|
sub rax, 1
|
||||||
|
cmp rax, 0
|
||||||
|
jl .skip_left
|
||||||
|
movzx rax, byte [r11 + rax]
|
||||||
|
cmp rax, 1
|
||||||
|
sete al
|
||||||
|
add dl, al
|
||||||
|
.skip_left:
|
||||||
|
|
||||||
|
; Check right
|
||||||
|
mov rax, r10
|
||||||
|
add rax, 1
|
||||||
|
cmp rax, 100
|
||||||
|
jge .skip_right
|
||||||
|
movzx rax, byte [r11 + rax]
|
||||||
|
cmp rax, 1
|
||||||
|
sete al
|
||||||
|
add dl, al
|
||||||
|
.skip_right:
|
||||||
|
|
||||||
|
; Check bottom left
|
||||||
|
mov rax, r10
|
||||||
|
add rax, 9
|
||||||
|
cmp rax, 100
|
||||||
|
jge .skip_bottom_left
|
||||||
|
movzx rax, byte [r11 + rax]
|
||||||
|
cmp rax, 1
|
||||||
|
sete al
|
||||||
|
add dl, al
|
||||||
|
.skip_bottom_left:
|
||||||
|
|
||||||
|
; Check bottom
|
||||||
|
mov rax, r10
|
||||||
|
add rax, 10
|
||||||
|
cmp rax, 100
|
||||||
|
jge .skip_bottom
|
||||||
|
movzx rax, byte [r11 + rax]
|
||||||
|
cmp rax, 1
|
||||||
|
sete al
|
||||||
|
add dl, al
|
||||||
|
.skip_bottom:
|
||||||
|
|
||||||
|
; Check bottom right
|
||||||
|
mov rax, r10
|
||||||
|
add rax, 11
|
||||||
|
cmp rax, 100
|
||||||
|
jge .skip_bottom_right
|
||||||
|
movzx rax, byte [r11 + rax]
|
||||||
|
cmp rax, 1
|
||||||
|
sete al
|
||||||
|
add dl, al
|
||||||
|
.skip_bottom_right:
|
||||||
|
ret
|
||||||
|
|||||||
150
src/ui/ui.asm
150
src/ui/ui.asm
@ -1,150 +0,0 @@
|
|||||||
; r8 = string
|
|
||||||
; r9 = length
|
|
||||||
print_String:
|
|
||||||
mov rax, 0x2000004
|
|
||||||
mov rdi, 1
|
|
||||||
mov rsi, r8
|
|
||||||
mov rdx, r9
|
|
||||||
syscall
|
|
||||||
ret
|
|
||||||
|
|
||||||
; r10 = current tile index
|
|
||||||
; r11 = board
|
|
||||||
; rdx = mine count
|
|
||||||
; r8 = offset
|
|
||||||
count_adjacent_mines:
|
|
||||||
; Compute current column: r12 = r10 mod 10
|
|
||||||
mov rax, r10
|
|
||||||
xor rdx, rdx
|
|
||||||
mov rcx, 10
|
|
||||||
div rcx
|
|
||||||
mov r12, rdx ; r12 holds the column index (0-9)
|
|
||||||
|
|
||||||
xor rdx, rdx ; rdx will accumulate the mine count
|
|
||||||
|
|
||||||
; Check top-left: valid if r10 >= 11 and column != 0
|
|
||||||
cmp r10, 11
|
|
||||||
jb .skip_top_left
|
|
||||||
cmp r12, 0
|
|
||||||
je .skip_top_left
|
|
||||||
mov rax, r10
|
|
||||||
sub rax, 11
|
|
||||||
movzx rax, byte [r11 + rax]
|
|
||||||
cmp rax, 1
|
|
||||||
sete al
|
|
||||||
add dl, al
|
|
||||||
.skip_top_left:
|
|
||||||
|
|
||||||
; Check top: valid if r10 >= 10
|
|
||||||
cmp r10, 10
|
|
||||||
jb .skip_top
|
|
||||||
mov rax, r10
|
|
||||||
sub rax, 10
|
|
||||||
movzx rax, byte [r11 + rax]
|
|
||||||
cmp rax, 1
|
|
||||||
sete al
|
|
||||||
add dl, al
|
|
||||||
.skip_top:
|
|
||||||
|
|
||||||
; Check top-right: valid if r10 >= 9 and column != 9
|
|
||||||
cmp r10, 9
|
|
||||||
jb .skip_top_right
|
|
||||||
cmp r12, 9
|
|
||||||
je .skip_top_right
|
|
||||||
mov rax, r10
|
|
||||||
sub rax, 9
|
|
||||||
movzx rax, byte [r11 + rax]
|
|
||||||
cmp rax, 1
|
|
||||||
sete al
|
|
||||||
add dl, al
|
|
||||||
.skip_top_right:
|
|
||||||
|
|
||||||
; Check left: valid if column != 0
|
|
||||||
cmp r12, 0
|
|
||||||
je .skip_left
|
|
||||||
mov rax, r10
|
|
||||||
sub rax, 1
|
|
||||||
movzx rax, byte [r11 + rax]
|
|
||||||
cmp rax, 1
|
|
||||||
sete al
|
|
||||||
add dl, al
|
|
||||||
.skip_left:
|
|
||||||
|
|
||||||
; Check right: valid if column != 9
|
|
||||||
cmp r12, 9
|
|
||||||
je .skip_right
|
|
||||||
mov rax, r10
|
|
||||||
add rax, 1
|
|
||||||
cmp rax, 100
|
|
||||||
jge .skip_right
|
|
||||||
movzx rax, byte [r11 + rax]
|
|
||||||
cmp rax, 1
|
|
||||||
sete al
|
|
||||||
add dl, al
|
|
||||||
.skip_right:
|
|
||||||
|
|
||||||
; Check bottom-left: valid if r10 < 90 and column != 0
|
|
||||||
cmp r10, 90
|
|
||||||
jae .skip_bottom_left
|
|
||||||
cmp r12, 0
|
|
||||||
je .skip_bottom_left
|
|
||||||
mov rax, r10
|
|
||||||
add rax, 9
|
|
||||||
movzx rax, byte [r11 + rax]
|
|
||||||
cmp rax, 1
|
|
||||||
sete al
|
|
||||||
add dl, al
|
|
||||||
.skip_bottom_left:
|
|
||||||
|
|
||||||
; Check bottom: valid if r10 < 90
|
|
||||||
cmp r10, 90
|
|
||||||
jae .skip_bottom
|
|
||||||
mov rax, r10
|
|
||||||
add rax, 10
|
|
||||||
movzx rax, byte [r11 + rax]
|
|
||||||
cmp rax, 1
|
|
||||||
sete al
|
|
||||||
add dl, al
|
|
||||||
.skip_bottom:
|
|
||||||
|
|
||||||
; Check bottom-right: valid if r10 < 90 and column != 9
|
|
||||||
cmp r10, 90
|
|
||||||
jae .skip_bottom_right
|
|
||||||
cmp r12, 9
|
|
||||||
je .skip_bottom_right
|
|
||||||
mov rax, r10
|
|
||||||
add rax, 11
|
|
||||||
movzx rax, byte [r11 + rax]
|
|
||||||
cmp rax, 1
|
|
||||||
sete al
|
|
||||||
add dl, al
|
|
||||||
.skip_bottom_right:
|
|
||||||
ret
|
|
||||||
|
|
||||||
; Print the board
|
|
||||||
; r10 = current tile index
|
|
||||||
; r11 = board
|
|
||||||
; r12 = column index
|
|
||||||
; rdx = mine count
|
|
||||||
; r8 = offset
|
|
||||||
fill_board:
|
|
||||||
xor r10, r10 ; Counter for filling the board
|
|
||||||
push rbp
|
|
||||||
mov rbp, rsp
|
|
||||||
push rcx
|
|
||||||
xor r10, r10 ; Counter
|
|
||||||
lea r11, [rel board] ; Load address of board
|
|
||||||
|
|
||||||
fill_loop:
|
|
||||||
rdrand rax
|
|
||||||
and rax, 15 ; Reduce probability of mine (1 in 16 chance)
|
|
||||||
cmp rax, 1
|
|
||||||
sete al ; Set al to 1 if rax == 1, otherwise 0
|
|
||||||
mov [r11 + r10], al ; Store at board[r10]
|
|
||||||
inc r10
|
|
||||||
cmp r10, 100 ; Check if we've filled 100 tiles
|
|
||||||
jb fill_loop
|
|
||||||
|
|
||||||
pop rcx
|
|
||||||
pop rbp
|
|
||||||
ret
|
|
||||||
Loading…
x
Reference in New Issue
Block a user