From 4165404f85bf542d5f7a42d81b7288a91a72296d Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Wed, 18 Feb 2026 09:11:17 +0100 Subject: feat: extract some function helpers --- src/SDL_interface.S | 26 ------------ src/helpers/function.S | 108 +++++++++++++++++++++++++++++++++++++++++++++++++ src/libs/sdl.S | 26 ++++++++++++ src/main.S | 46 ++++++++++----------- 4 files changed, 156 insertions(+), 50 deletions(-) delete mode 100644 src/SDL_interface.S create mode 100644 src/helpers/function.S create mode 100644 src/libs/sdl.S diff --git a/src/SDL_interface.S b/src/SDL_interface.S deleted file mode 100644 index 02302b4..0000000 --- a/src/SDL_interface.S +++ /dev/null @@ -1,26 +0,0 @@ -#define SDL_INIT_TIMER 0x00000001u -#define SDL_INIT_AUDIO 0x00000010u -#define SDL_INIT_VIDEO 0x00000020u -#define SDL_INIT_JOYSTICK 0x00000200u -#define SDL_INIT_HAPTIC 0x00001000u -#define SDL_INIT_GAMECONTROLLER 0x00002000u - -#define SDL_WINDOW_SHOWN 0x00000004u - -#define SDL_WINDOWPOS_UNDEFINED 0x1FFF0000u - -// int SDL_Init(uint32_t flags) -.type SDL_Init, @function -.extern SDL_Init - -// SDL_Window * SDL_CreateWindow(const char *title, int x, int y, int w, int h, uint32_t flags) -.type SDL_CreateWindow, @function -.extern SDL_CreateWindow - -// void SDL_DestroyWindow(SDL_Window *window) -.type SDL_DestroyWindow, @function -.extern SDL_DestroyWindow - -// void SDL_Quit(void) -.type SDL_Quit, @function -.extern SDL_Quit \ No newline at end of file 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/libs/sdl.S b/src/libs/sdl.S new file mode 100644 index 0000000..02302b4 --- /dev/null +++ b/src/libs/sdl.S @@ -0,0 +1,26 @@ +#define SDL_INIT_TIMER 0x00000001u +#define SDL_INIT_AUDIO 0x00000010u +#define SDL_INIT_VIDEO 0x00000020u +#define SDL_INIT_JOYSTICK 0x00000200u +#define SDL_INIT_HAPTIC 0x00001000u +#define SDL_INIT_GAMECONTROLLER 0x00002000u + +#define SDL_WINDOW_SHOWN 0x00000004u + +#define SDL_WINDOWPOS_UNDEFINED 0x1FFF0000u + +// int SDL_Init(uint32_t flags) +.type SDL_Init, @function +.extern SDL_Init + +// SDL_Window * SDL_CreateWindow(const char *title, int x, int y, int w, int h, uint32_t flags) +.type SDL_CreateWindow, @function +.extern SDL_CreateWindow + +// void SDL_DestroyWindow(SDL_Window *window) +.type SDL_DestroyWindow, @function +.extern SDL_DestroyWindow + +// void SDL_Quit(void) +.type SDL_Quit, @function +.extern SDL_Quit \ No newline at end of file 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 + -- cgit v1.2.3