I am making a snake game in x86-64 assembly for Linux using syscalls and basic c stdlib. I made a function to set the cursor position in the terminal that is called at each iteration of the game loop after having waited 1 second (1s for debugging, much less in the real game). If I don't sleep, the cursor moves successfully but it doesn't if I do. Here is my code:
global main
extern putc
extern printf
extern fflush
%define MAP_WIDTH 20
%define MAP_HEIGHT 20
%define MAP_COUNT (MAP_WIDTH * MAP_HEIGHT)
%define SCREEN_WIDTH (MAP_WIDTH + 1)
%define SCREEN_HEIGHT MAP_HEIGHT
%define SCREEN_COUNT (SCREEN_WIDTH * SCREEN_HEIGHT)
%define WAIT_TIME_NS (150 * 10^6)
%define MAX_SNAKE_LENGTH MAP_COUNT
section .text
; Functions: rdi, rsi, rdx, rcx, r8, r9
; Syscalls: rax, rdi, rsi, rdx
clear_console:
mov rax, 1 ; RAX: Syscall #1 : Write
mov rdi, 1 ; RDI: File Handle #1 : Stdout
mov rdx, CLEAR_CMD_LEN ; RDX: Length
mov rsi, CLEAR_CMD ; RSI: char*
syscall ; Perform the syscall
ret
sleep_before_next_iteration:
mov rax, 35 ; RAX: Syscall #35: sys_nanosleep
mov rdi, SLEEP_TIMESPEC ; RDI: req: pointer to struct timespec.
xor rsi, rsi ; RSI: mem: struct timespec* (NULL here)
syscall ; Perform the syscall
ret
exit_program:
mov rax, 60 ; RAX: Syscall #60: Exit
xor rdi, rdi ; RDI: Error Code 0: Clean Exit
syscall ; Call Syscall
ret
go_to_location: ; Args (rdi: x, rsi: y)
; Move Cursor To Position
mov rdx, rsi ; Argument 2; %d for y
mov rsi, rdi ; Argument 1: %d for x
mov rdi, MOVE_CURSOR_CMD ; Argument 0: string to format
call printf
ret
main:
call clear_console
game_loop_iterate:
call sleep_before_next_iteration
; Print Apple
mov rdi, 5 ; goto x
mov rsi, 7 ; goto y
call go_to_location
mov rax, 1 ; RAX: Syscall #1 : Write
mov rdi, 1 ; RDI: File Handle #1 : Stdout
mov rdx, 1 ; RDX: Length
mov rsi, APPLE_STR ; RSI: char*
syscall ; Perform the syscall
jmp game_loop_iterate
game_loop_end:
call exit_program
ret
section .data:
SLEEP_TIMESPEC: dq 1, 0
APPLE_STR: db "apple string", 0
MOVE_CURSOR_CMD: db 0x1B, "[%d;%df", 0
CLEAR_CMD: db 27,"[H",27,"[2J" ; Clear Console Command
CLEAR_CMD_LEN: equ $-CLEAR_CMD ; Length Of The Clear Console Command
Any help would be much appreciated! I don't think that sys_nanosleep
is the root cause of this issue since it just sleeps but I've been searching for about half a day.
Info:
- Kernel: 5.4.0-42-generic
- OS: Ubuntu 20.04 LTS
Building:
nasm -felf64 -g ./snake.asm
clang snake.o -o snake
Thanks!