aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Morgner <felix.morgner@gmail.com>2026-02-18 09:11:17 +0100
committerFelix Morgner <felix.morgner@gmail.com>2026-02-18 09:11:17 +0100
commit4165404f85bf542d5f7a42d81b7288a91a72296d (patch)
tree0a25342460cfca9da700dc81cfc22c8160c1452e
parent6e6ee64bb4cf10a98c7bd92e06090502eb67e402 (diff)
downloadsnake.s-4165404f85bf542d5f7a42d81b7288a91a72296d.tar.xz
snake.s-4165404f85bf542d5f7a42d81b7288a91a72296d.zip
feat: extract some function helpers
-rw-r--r--src/helpers/function.S108
-rw-r--r--src/libs/sdl.S (renamed from src/SDL_interface.S)0
-rw-r--r--src/main.S46
3 files changed, 130 insertions, 24 deletions
diff --git a/src/helpers/function.S b/src/helpers/function.S
new file mode 100644
index 0000000..c6647e9
--- /dev/null
+++ b/src/helpers/function.S
@@ -0,0 +1,108 @@
+.set _FUNCTION_IS_IN_FUNCTION_DEFINITION, 0
+.set _FUNCTION_LOCALS_ALLOCATED, 0
+
+.macro _function_local_variable scope, name, size
+ .if _FUNCTION_IS_IN_FUNCTION_DEFINITION == 0
+ .error "Cannot define a local variable outside of a function."
+ .else
+ .set _FRAME_OFFSET, _FRAME_OFFSET + \size
+ .equ \scope\()_name, -_FRAME_OFFSET
+ .endif
+.endm
+
+.macro _function_allocate_local_variables scope
+ .if _FUNCTION_IS_IN_FUNCTION_DEFINITION == 0
+ .error "Cannot allocate local variables outside of a function."
+ .elseif _FUNCTION_LOCALS_ALLOCATED == 1
+ .error "Local variables have already been allocated."
+ .else
+ .set _FUNCTION_LOCALS_ALLOCATED, 1
+ .equ \scope\()_FRAME_SIZE, (_FRAME_OFFSET + 15) & -16
+ .if \scope\()_FRAME_SIZE > 0
+ sub $\scope\()_FRAME_SIZE, %rsp
+ .endif
+ .endif
+.endm
+
+.macro _function_load_local scope, name, register
+ .if _FUNCTION_IS_IN_FUNCTION_DEFINITION == 0
+ .error "Cannot load a local variable outside of a function."
+ .elseif _FUNCTION_LOCALS_ALLOCATED == 0
+ .error "Local variables have not been allocated."
+ .else
+ mov \scope\()_name(%rbp), \register
+ .endif
+.endm
+
+.macro _function_store_local scope, register, name
+ .if _FUNCTION_IS_IN_FUNCTION_DEFINITION == 0
+ .error "Cannot store a local variable outside of a function."
+ .elseif _FUNCTION_LOCALS_ALLOCATED == 0
+ .error "Local variables have not been allocated."
+ .else
+ mov \register, \scope\()_name(%rbp)
+ .endif
+.endm
+
+.macro function_begin name
+ .if _FUNCTION_IS_IN_FUNCTION_DEFINITION == 1
+ .error "Cannot define a function inside of another function."
+ .endif
+
+ .set _FUNCTION_IS_IN_FUNCTION_DEFINITION, 1
+ .set _FUNCTION_LOCALS_ALLOCATED, 0
+
+ .macro define_local var_name, var_size
+ _function_local_variable \name, \var_name, \var_size
+ .endm
+
+ .macro allocate_locals
+ _function_allocate_local_variables \name
+ .endm
+
+ .macro load_local var_name, register
+ _function_load_local \name, \var_name, \register
+ .endm
+
+ .macro store_local register, var_name
+ _function_store_local \name, \register, \var_name
+ .endm
+
+ .macro function_exit
+ jmp .Lexit_\name
+ .endm
+
+ .macro function_end
+ .if _FRAME_OFFSET > 0
+ .if _FUNCTION_LOCALS_ALLOCATED == 0
+ .error "Local variables were never been allocated."
+ .endif
+ .endif
+
+ .Lexit_\name:
+ leave
+ .cfi_def_cfa %rsp, 8
+ ret
+ .cfi_endproc
+ .size \name, .-\name
+ .set _FUNCTION_IS_IN_FUNCTION_DEFINITION, 0
+ .set _FUNCTION_LOCALS_ALLOCATED, 0
+ .purgem allocate_locals
+ .purgem function_end
+ .purgem function_exit
+ .purgem load_local
+ .purgem define_local
+ .purgem store_local
+ .endm
+
+ .globl \name
+ .type \name, @function
+ \name:
+ .cfi_startproc
+ push %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset %rbp, -16
+ mov %rsp, %rbp
+ .cfi_def_cfa_register %rbp
+ .set _FRAME_OFFSET, 0
+.endm
diff --git a/src/SDL_interface.S b/src/libs/sdl.S
index 02302b4..02302b4 100644
--- a/src/SDL_interface.S
+++ b/src/libs/sdl.S
diff --git a/src/main.S b/src/main.S
index 0a21f83..50e894d 100644
--- a/src/main.S
+++ b/src/main.S
@@ -1,4 +1,5 @@
-#include "SDL_interface.S"
+#include "helpers/function.S"
+#include "libs/sdl.S"
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
@@ -14,13 +15,9 @@
window_title: .string "snake.s"
.section .text
- .global main
- // void _print_sdl_error(char const * format)
- .type _print_sdl_error, @function
- _print_sdl_error:
- push %rbp
- mov %rsp, %rbp
+ //! @function _print_sdl_error(char const * format)
+ function_begin _print_sdl_error
push %rdi
sub $8, %rsp
@@ -32,27 +29,25 @@
pop %rdi
call printf@PLT
- jmp .Lexit
- leave
- ret
+ function_end
- .type main, @function
- main:
- push %rbp
- mov %rsp, %rbp
+ function_begin main
+
+ define_local window_handle, 8
+ allocate_locals
// initialize SDL
mov $SDL_INIT_VIDEO, %rdi
call SDL_Init@PLT
// check if initialization was successful
- cmp $0, %rax
+ test %rax, %rax
jae 1f
lea failed_to_initialize_sdl(%rip), %rdi
call _print_sdl_error@PLT
mov $1, %rax
- jmp .Lexit
+ function_exit
1:
// create a window
@@ -64,17 +59,21 @@
mov $SDL_WINDOW_SHOWN, %r9
call SDL_CreateWindow@PLT
- cmp $0, %rax
+ store_local %rax, window_handle
+
+ // check if window creation was successful
+ test %rax, %rax
jne 1f
lea failed_to_create_window(%rip), %rdi
call _print_sdl_error@PLT
mov $1, %rax
- jmp .Lexit
+ function_exit
1:
- mov %rax, %rdi
- call SDL_DestroyWindow@PLT
- call SDL_Quit@PLT
+ load_local window_handle, %rdi
+ call SDL_DestroyWindow@PLT
+
+ call SDL_Quit@PLT
.Lsuccess:
lea greeting(%rip), %rdi
@@ -83,6 +82,5 @@
xor %rax, %rax
- .Lexit:
- leave
- ret
+ function_end
+