1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
#include "helpers/function.S"
#include "SDL/events.S"
#include "SDL/init.S"
#include "SDL/rect.S"
#include "SDL/render.S"
#include "SDL/video.S"
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
// integer-params: RDI, RSI, RDX, RCX, R8, R9
// caller-saved: RAX, RCX, RDI, RSI, RDX, R8-R11
// callee-saved: RBX, RSP, RBP, R12-R15
.section .rodata
failed_to_create_renderer: .string "Renderer could not be created\nSDL_error: %s\n"
failed_to_create_window: .string "Window could not be created\nSDL_error: %s\n"
failed_to_initialize_sdl: .string "SDL could not be initialized\nSDL_error: %s\n"
succeeded_to_create_renderer: .string "Renderer created successfully!\n"
succeeded_to_create_window: .string "Window created successfully!\n"
succeeded_to_initialize_sdl: .string "SDL2 initialized successfully!\n"
window_title: .string "snake.s"
.section .text
function_begin main
push %r12
push %r13
define_local window_handle, 8
define_local renderer_handle, 8
define_local rect, SIZE_SDL_Rect
define_local event, SIZE_SDL_Event
allocate_locals
// initialize SDL
mov $SDL_INIT_VIDEO, %rdi
call SDL_Init@PLT
// check if initialization was successful
test %rax, %rax
jae 1f
lea failed_to_initialize_sdl(%rip), %rdi
call _print_sdl_error@PLT
mov $1, %rax
function_exit
1:
lea succeeded_to_initialize_sdl(%rip), %rdi
xor %rax, %rax
call printf@PLT
// create a window
lea window_title(%rip), %rdi
mov $SDL_WINDOWPOS_UNDEFINED, %rsi
mov $SDL_WINDOWPOS_UNDEFINED, %rdx
mov $SCREEN_WIDTH, %rcx
mov $SCREEN_HEIGHT, %r8
mov $SDL_WINDOW_SHOWN, %r9
call SDL_CreateWindow@PLT
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 .Lquit_sdl
1:
lea succeeded_to_create_window(%rip), %rdi
xor %rax, %rax
call printf@PLT
// create a renderer
load_local window_handle, %rdi
mov $-1, %rsi
mov $(SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), %rdx
call SDL_CreateRenderer@PLT
store_local %rax, renderer_handle
// check if renderer creation was successful
test %rax, %rax
jne 1f
lea failed_to_create_renderer(%rip), %rdi
call _print_sdl_error@PLT
jmp .Ldestroy_window
1:
lea succeeded_to_create_renderer(%rip), %rdi
xor %rax, %rax
call printf@PLT
// initialize a simple square, located at the screen's center
mov $(SCREEN_HEIGHT / 2), %r8d
mov $(SCREEN_WIDTH / 2), %r9d
address_of_local rect, %rdi
mov %r8d, OFFSET_SDL_Rect_w(%rdi)
mov %r8d, OFFSET_SDL_Rect_h(%rdi)
mov %r9d, %r10d
shr $1, %r8d
sub %r8d, %r10d
mov %r10d, OFFSET_SDL_Rect_x(%rdi)
mov %r8d, OFFSET_SDL_Rect_y(%rdi)
//! @var bool quit_requested
xor %r12, %r12
// main loop
.Lloop:
address_of_local event, %rdi
mov %rdi, %r13
call SDL_PollEvent@PLT
mov (%r13), %r8d
// user requested to quit
cmp $SDL_EVENT_QUIT, %r8d
je .Lloop_end
// use white color
load_local renderer_handle, %rdi
mov %rdi, %r13
mov $0xff, %rsi
mov %rsi, %rcx
mov %rsi, %rdx
mov %rsi, %r8
call SDL_SetRenderDrawColor@PLT
test %rax, %rax
// clear the screen
mov %r13, %rdi
call SDL_RenderClear@PLT
// use red color
mov %r13, %rdi
mov $0xff, %rsi
mov $0x00, %rcx
mov $0x00, %rdx
mov %rsi, %r8
call SDL_SetRenderDrawColor@PLT
// draw the square
mov %r13, %rdi
address_of_local rect, %rsi
call SDL_RenderFillRect@PLT
// update the screen
mov %r13, %rdi
call SDL_RenderPresent@PLT
jmp .Lloop
.Lloop_end:
.Ldestroy_renderer:
// destroy the renderer
load_local renderer_handle, %rdi
call SDL_DestroyRenderer@PLT
.Ldestroy_window:
// destroy the window
load_local window_handle, %rdi
call SDL_DestroyWindow@PLT
.Lquit_sdl:
call SDL_Quit@PLT
xor %rax, %rax
pop %r13
pop %r12
function_end
|