-
Notifications
You must be signed in to change notification settings - Fork 20
/
maze.s
130 lines (117 loc) · 2.69 KB
/
maze.s
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
// Maze generator in x86-64 assembly language
// Joe Wingbermuehle
// 2013-04-20
// The size of the maze (must be odd)
.set width, 39
.set height, 21
.globl _main
.text
_main:
pushq %rbp
movq %rsp, %rbp
// Seed the random number generator.
xorq %rdi, %rdi
callq _time
movq %rax, %rdi
callq _srand
// Initialize the maze array.
movq $width * height, %rcx
leaq maze(%rip), %rdi
xorb %al, %al
rep stosb
incb %al
movq $width, %rcx
leaq maze(%rip), %rdi
push %rcx
rep stosb
pop %rcx
leaq maze + width * (height - 1)(%rip), %rdi
rep stosb
leaq maze(%rip), %rdi
movq $width, %rcx
initialize_sides:
movb %al, (%rdi)
addq $width - 1, %rdi
movb %al, (%rdi)
incq %rdi
loop initialize_sides
// Carve the maze
leaq maze + width * 2 + 2(%rip), %r12
callq carve_maze
// Carve the start/finish.
leaq maze + width + 2(%rip), %rdi
movb $1, (%rdi)
leaq maze + width * (height - 2) + width - 3(%rip), %rdi
movb $1, (%rdi)
// Display the maze.
leaq maze(%rip), %rbx
movq $height, %rcx
print_maze_y:
movq %rcx, %r12
movq $width, %rcx
print_maze_x:
movq %rcx, %r13
leaq wall_str(%rip), %rdi
movb (%rbx), %al
or %al, %al
jz print_maze_continue
leaq space_str(%rip), %rdi
print_maze_continue:
xorq %rsi, %rsi
callq _printf
incq %rbx
movq %r13, %rcx
loop print_maze_x
leaq nl_str(%rip), %rdi
xorq %rsi, %rsi
callq _printf
movq %r12, %rcx
loop print_maze_y
// Return.
xorq %rax, %rax
popq %rbp
ret
// Carve the maze.
carve_maze:
pushq %rbp
movq %rsp, %rbp
carve_maze_again:
callq _rand
andq $3 << 3, %rax
movq %rax, %r15
movq $4, %r14
movq %r12, %rdi
movb $1, (%rdi)
carve_maze_loop:
leaq offsets(%rip), %rsi
addq %r15, %rsi
movq (%rsi), %rdx
movq %rdx, %rax
addq %rdi, %rax
movb (%rax), %bl
addq %rax, %rdx
orb (%rdx), %bl
jnz carve_maze_continue
incb %bl
movb %bl, (%rax)
movb %bl, (%rdx)
movq %rdx, %r12
pushq %r12
subq $8, %rsp
callq carve_maze
addq $8, %rsp
popq %r12
jmp carve_maze_again
carve_maze_continue:
addq $8, %r15
andq $3 << 3, %r15
decq %r14
jnz carve_maze_loop
popq %rbp
ret
.data
wall_str: .asciz "[]"
space_str: .asciz " "
nl_str: .asciz "\n"
offsets: .quad 1, -1, width, -width
.lcomm maze, width * height + 8