Created
June 22, 2014 12:35
-
-
Save makenowjust/6a0440fc2deaafb6dcbe to your computer and use it in GitHub Desktop.
x86-64でFizzBuzzしてみた ref: http://qiita.com/make_now_just/items/5d659b17637ec1f32c37
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# .rodataには定数を置く | |
.section .rodata | |
fizz: .ascii "Fizz" | |
buzz: .ascii "Buzz" | |
# .dataには変数を置く | |
.section .data | |
char: .ascii "0" | |
# .textにはプログラムを置く | |
.section .text | |
.global _start | |
_start: | |
xor %r8, %r8 # %r8 = 0 | |
loop.begin: | |
inc %r8 # %r8 += 1 | |
cmp $101, %r8 # if (%r8 == 101) | |
je loop.break # goto loop.break | |
xor %rdx, %rdx # %rdx = 0 | |
mov %r8, %rax # %rax = %r8 | |
mov $3, %r9 # %r9 = 3 | |
div %r9 # %rax = %rdx:%rax / %r9, %rdx = %rdx:%rax % %r9 | |
mov %rdx, %r10 # %r10 = %rdx | |
xor %rdx, %rdx # %rdx = 0 | |
mov %r8, %rax # %rax = %r8 | |
mov $5, %r9 # %r9 = 3 | |
div %r9 # %rax = %rdx:%rax / %r9, %rdx = %rdx:%rax % %r9 | |
mov %rdx, %r11 # %r11 = %rdx | |
cmp $0, %r10 # if (%r10 == 0) // 3で割り切れるとき | |
je loop.fizz # goto loop.fizz | |
cmp $0, %r11 # if (%r11 == 0) // 5で割り切れるとき | |
je loop.buzz # goto loop.buzz | |
jmp loop.int # goto loop.int | |
loop.fizz: | |
cmp $0, %r11 # if (%r11 == 0) // 3と5で割り切れるとき | |
je loop.fizzbuzz # goto loop.fizzbuzz | |
call print_fizz # print_fizz() | |
jmp loop.end # goto loop.end | |
loop.buzz: | |
call print_buzz # print_buzz() | |
jmp loop.end # goto loop.end | |
loop.fizzbuzz: | |
call print_fizz # print_fizz() | |
call print_buzz # print_buzz() | |
jmp loop.end # goto loop.end | |
loop.int: | |
mov %r8, %r9 # %r9 = %r8 | |
call print_int # print_int(%r9) | |
loop.end: | |
call newline # newline() | |
jmp loop.begin # goto loop.begin | |
loop.break: | |
call exit0 # exit0() | |
# fizzと表示する | |
print_fizz: | |
lea fizz(%rip), %rsi | |
mov $4, %rdx | |
call print | |
ret | |
# buzzと表示する | |
print_buzz: | |
lea buzz(%rip), %rsi | |
mov $4, %rdx | |
call print | |
ret | |
# 改行する | |
newline: | |
mov $0x0a, %r11 | |
mov %r11, char(%rip) | |
lea char(%rip), %rsi | |
xor %rdx, %rdx | |
inc %rdx | |
call print | |
ret | |
# %r9に渡された3桁以内の数値を文字列として表示する(%rax, %rdx, %r11, %r12を使用) | |
print_int: | |
# 100で割り、商が0以外のとき文字にして表示 | |
# つまり、3桁目(100の位)の数値を表示 | |
xor %rdx, %rdx # %rdx = 0 | |
mov %r9, %rax # %rax = %r9 | |
mov $100, %r11 # %r11 = 100 | |
div %r11 # %rax = %rdx:%rax / %r11, %rdx = %rdx:%rax % %r11 | |
cmp $0, %rax # if (%rax == 0) | |
je print_int.1 # goto print_int.1 | |
mov %rdx, %r9 # %r9 = %rdx | |
xor %rdx, %rdx # %rdx = 0 | |
inc %rdx # %rdx += 1 (==> %rdx = 1) | |
add $0x30, %rax # %rax += 0x30 | |
mov %rax, char(%rip) # *char = %rax | |
lea char(%rip), %rsi # %rsi = char | |
call print # print (%rsi, %rdx) | |
print_int.1: | |
# 10で割り、商が0以外のとき文字にして表示 | |
# つまり、2桁目(10の位)の数値を表示 | |
xor %rdx, %rdx # %rdx = 0 | |
mov %r9, %rax # %rax = %r9 | |
mov $10, %r11 # %r11 = 10 | |
div %r11 # %rax = %rdx:%rax / %r11, %rdx = %rdx:%rax % %r11 | |
cmp $0, %rax # if (%rax == 0) | |
je print_int.2 # goto print_int.2 | |
mov %rdx, %r9 # %r9 = %rdx | |
xor %rdx, %rdx # %rdx = 0 | |
inc %rdx # %rdx += 1 (==> %rdx = 1) | |
add $0x30, %rax # %rax += 0x30 | |
mov %rax, char(%rip) # *char = %rax | |
lea char(%rip), %rsi # %rsi = char | |
call print # print(%rsi, %rdx) | |
print_int.2: | |
# 1の位の数値を表示 | |
add $0x30, %r9 # %r9 += 0x30 | |
mov %r9, char(%rip) # *char = %r9 | |
lea char(%rip), %rsi # %rsi = char | |
call print # print(%rsi, %rdx) | |
ret # return | |
# %rsiに指定されたアドレスから、%rdx文字数分だけ表示する | |
print: | |
xor %rax, %rax | |
inc %rax | |
mov %rax, %rdi | |
# %rax = 1 (syswrite) | |
# %rdi = 1 (stdout) | |
syscall | |
ret | |
# リターンコード0で終了する | |
exit0: | |
xor %rax, %rax | |
mov %rax, %rdi | |
mov $60, %al | |
# %rax = 60 (sysexit) | |
# %rdi = 0 | |
syscall |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment