-
Notifications
You must be signed in to change notification settings - Fork 130
/
Copy pathfizzbuzz.s
93 lines (75 loc) · 2.03 KB
/
fizzbuzz.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
.global main
.text
.align 2
/* FizzBuzz - a classic interview question.
Count from 0 to n (let's make it 100).
If the value is divisible by 3, print Fizz
If the value is divisible by 5, print Buzz
If the value is divisible by both 3 and 5, print FizzBuzz
Otherwise, print the number.
*/
/* Bible:
x20 counter
w21 bool that says whether or not I have printed anything
*/
/* mod(a, b) - implements a % b
a comes to us in x0
b comes to us in x1
method:
integer divide a by b - for example - 5 % 3
would need 5 // 3 yielding 1
multiply result by b - 1 * 3 is 3
subtract result from a - 5 - 3 yielding 2
and that's our return value.
*/
mod: sdiv x2, x0, x1 // x2 gets a // b
msub x0, x2, x1, x0 // x0 gets a - a // b * b
ret
main: stp x20, x30, [sp, -16]!
str x21, [sp, -16]!
mov x20, xzr
1: cmp x20, 100
bge 99f
mov w21, wzr
// Test for divisible by 3
mov x0, x20
mov x1, 3
bl mod
cbnz x0, 5f
// If we get here, the counter was divisible by 3
ldr x0, =fizz
bl printf
add w21, w21, 1
5: mov x0, x20
mov x1, 5
bl mod
cbnz x0, 10f
// If we get here, the counter was divisible by 5
ldr x0, =buzz
bl printf
add w21, w21, 1
10: cbz w21, 20f
// If we get here, it means that we have printed
// something (either fizz, or buzz or fizzbuzz)
// so all we need now is a new line
ldr x0, =nl
bl puts
b 80f
20: // If we get here, the counter was neither a
// multiple of 3 nor of 5. Therefore, we need
// to print the counter itself.
ldr x0, =fmt
mov x1, x20
bl printf
80: add x20, x20, 1
b 1b
99: ldr x21, [sp], 16
ldp x20, x30, [sp], 16
mov w0, wzr
ret
.data
fizz: .asciz "Fizz"
buzz: .asciz "Buzz"
nl: .asciz ""
fmt: .asciz "%ld\n"
.end