Thanks for using Compiler Explorer
Sponsors
Jakt
C++
Ada
Algol68
Analysis
Android Java
Android Kotlin
Assembly
C
C3
Carbon
C with Coccinelle
C++ with Coccinelle
C++ (Circle)
CIRCT
Clean
Clojure
CMake
CMakeScript
COBOL
C++ for OpenCL
MLIR
Cppx
Cppx-Blue
Cppx-Gold
Cpp2-cppfront
Crystal
C#
CUDA C++
D
Dart
Elixir
Erlang
Fortran
F#
GLSL
Go
Haskell
HLSL
Helion
Hook
Hylo
IL
ispc
Java
Julia
Kotlin
LLVM IR
LLVM MIR
Modula-2
Mojo
Nim
Numba
Nix
Objective-C
Objective-C++
OCaml
Odin
OpenCL C
Pascal
Perl
Pony
PTX
Python
Racket
Raku
Ruby
Rust
Sail
Snowball
Scala
Slang
Solidity
Spice
SPIR-V
Swift
LLVM TableGen
Toit
Triton
TypeScript Native
V
Vala
Visual Basic
Vyper
WASM
Yul (Solidity IR)
Zig
Javascript
GIMPLE
Ygen
sway
assembly source #1
Output
Compile to binary object
Link to binary
Execute the code
Intel asm syntax
Demangle identifiers
Verbose demangling
Filters
Unused labels
Library functions
Directives
Comments
Horizontal whitespace
Debug intrinsics
Compiler
AArch64 binutils (trunk)
AArch64 binutils 2.24
AArch64 binutils 2.28
AArch64 binutils 2.29
AArch64 binutils 2.30
AArch64 binutils 2.31.1
AArch64 binutils 2.32
AArch64 binutils 2.33.1
AArch64 binutils 2.34
AArch64 binutils 2.35.1
AArch64 binutils 2.35.2
AArch64 binutils 2.36.1
AArch64 binutils 2.37
AArch64 binutils 2.38
AArch64 binutils 2.39
AArch64 binutils 2.40
AArch64 binutils 2.41
AArch64 binutils 2.42
AArch64 binutils 2.43
AArch64 binutils 2.45
AArch64 clang (assertions trunk)
AArch64 clang (trunk)
AArch64 clang 10.0.0
AArch64 clang 10.0.1
AArch64 clang 11.0.0
AArch64 clang 11.0.1
AArch64 clang 12.0.0
AArch64 clang 12.0.1
AArch64 clang 13.0.0
AArch64 clang 14.0.0
AArch64 clang 15.0.0
AArch64 clang 16.0.0
AArch64 clang 17.0.1
AArch64 clang 18.1.0
AArch64 clang 19.1.0
AArch64 clang 20.1.0
AArch64 clang 21.1.0
AArch64 clang 9.0.0
ARM binutils 2.25
ARM binutils 2.28
ARM binutils 2.31.1
ARM gcc 10.2 (linux)
ARM gcc 13.2 (linux)
ARM gcc 15.1 (linux)
ARM gcc 9.3 (linux)
ARMhf binutils 2.28
BeebAsm 1.09
BeebAsm 1.10
BeebAsm 1.11
NASM 2.12.02
NASM 2.13.02
NASM 2.13.03
NASM 2.14.02
NASM 2.16.01
NASM 3.00
NASM 3.01
RISC-V binutils 2.31.1
RISC-V binutils 2.31.1
RISC-V binutils 2.35.1
RISC-V binutils 2.35.1
RISC-V binutils 2.37.0
RISC-V binutils 2.37.0
RISC-V binutils 2.38.0
RISC-V binutils 2.38.0
RISC-V binutils 2.42.0
RISC-V binutils 2.42.0
RISC-V binutils 2.45.0
RISC-V binutils 2.45.0
ca65 (trunk)
ca65 2.17
ca65 2.18
ca65 2.19
x86-64 binutils (trunk)
x86-64 binutils 2.27
x86-64 binutils 2.28
x86-64 binutils 2.29.1
x86-64 binutils 2.34
x86-64 binutils 2.36.1
x86-64 binutils 2.38
x86-64 binutils 2.42
x86-64 binutils 2.45
x86-64 clang (assertions trunk)
x86-64 clang (trunk)
x86-64 clang 10.0.0
x86-64 clang 10.0.1
x86-64 clang 11.0.0
x86-64 clang 11.0.1
x86-64 clang 12.0.0
x86-64 clang 12.0.1
x86-64 clang 13.0.0
x86-64 clang 14.0.0
x86-64 clang 15.0.0
x86-64 clang 16.0.0
x86-64 clang 17.0.1
x86-64 clang 18.1.0
x86-64 clang 19.1.0
x86-64 clang 20.1.0
x86-64 clang 21.1.0
x86-64 clang 22.1.0
x86-64 clang 3.0.0
x86-64 clang 3.1
x86-64 clang 3.2
x86-64 clang 3.3
x86-64 clang 3.4.1
x86-64 clang 3.5
x86-64 clang 3.5.1
x86-64 clang 3.5.2
x86-64 clang 3.6
x86-64 clang 3.7
x86-64 clang 3.7.1
x86-64 clang 3.8
x86-64 clang 3.8.1
x86-64 clang 3.9.0
x86-64 clang 3.9.1
x86-64 clang 4.0.0
x86-64 clang 4.0.1
x86-64 clang 5.0.0
x86-64 clang 6.0.0
x86-64 clang 7.0.0
x86-64 clang 8.0.0
x86-64 clang 9.0.0
Options
Source code
bits 64 ; AMD64 SysV64 calling convention: ; function argument registers: RDI, RSI, RDX, RCX, R8, R9, XMM0–7, additional arguments are stored RTL on stack ; callee saved: RBX, RBP, R12–R15, it must restore their original values before returning control to the caller. ; All other registers must be saved by the caller if it wishes to preserve their values. ; ; Integral return values up to 64 bits in size are stored in RAX while values up to 128 bit are stored in RAX:RDX. ; Floating-point return values are similarly stored in XMM0 and XMM1. ; ; Kernel mode SysCall convention: ; Syscall selector is in RAX ; Function arguments: RDI, RSI, RDX, R10, R8, R9, No arguments are passed on the stack. ; RCX and R11 are clobbered ; SysCall result is returned in RAX, -4095 -> -1 indicates an error. ; ; FizzBuzz from 1-100 print fizz on multiples of 3, buzz on multiples of 5, and fizzbuzz on multiples of 15 ; nasm -f elf64 -g -F dwarf -o fizzbuzz.o fizzbuzz.S ; ld -o fizzbuzz fizzbuzz.o ; ./fizzbuzz ; ; "pauses" on end of output, enter anything to exit ; struc controlStruct .is_div_3 resw 1 .is_div_5 resw 1 .number resd 1 endstruc SECTION .data const_fizz: db "fizz" const_fizzLen: equ $-const_fizz const_buzz: db "buzz" const_buzzLen: equ $-const_buzz SECTION .bss buf: resb 16 ; 16 byte char buffer, which is much more than we need bufLen: resd 1 control: resb controlStruct_size ; using a structure in bss because it is easier to manage than adjusting the stack pointer ; not the best way to do this, I know. SECTION .text GLOBAL _start _start: nop ; gdb seems to like having the nop here, idk. mov [control + controlStruct.number], dword 1 mov r8d, dword [control + controlStruct.number] fizzbuzz: mov eax, r8d xor edx, edx div dword [rel div_base3] ; dividend in edx:eax -> quotient in eax, remainder in edx mov [control + controlStruct.is_div_3], dx mov eax, r8d xor edx, edx div dword [rel div_base5] mov [control + controlStruct.is_div_5], dx cmp r8d, 100 jg wait_and_exit call is_fizz call is_buzz call is_number lea rdi, [base10] mov esi, 1 call put_string inc r8d mov [control + controlStruct.number], r8d jmp fizzbuzz is_fizz: xor eax, eax mov ax, word [control + controlStruct.is_div_3] cmp ax, 0 jne is_fizz.return ; if control.is_div_3 isn't zero then it isn't a multiple of 3 lea rdi, [const_fizz] mov esi, const_fizzLen call put_string .return: ret is_buzz: xor eax, eax mov ax, word [control + controlStruct.is_div_5] cmp ax, 0 jne is_buzz.return ; if control.is_div_5 isn't zero then it isn't a multiple of 5 lea rdi, [const_buzz] mov esi, const_buzzLen call put_string .return: ret is_number: xor eax, eax mov ax, word [control + controlStruct.is_div_3] cmp ax, 0 je is_number.return mov ax, word [control + controlStruct.is_div_5] cmp ax, 0 je is_number.return lea rdi, [control + controlStruct.number] call display_number .return: ret display_number: xor ecx, ecx ; character count xor ebx, ebx ; buf offset mov eax, [rdi] .do_div: xor edx, edx ; ensure edx is zeroed because of div EDX:EAX/10 div dword [rel base10] ; dividend in edx:eax -> quotient in eax, remainder in edx or dl, '0' ; convert to ascii represetation push rdx ; store on stack to pop off in the correct order later inc ecx test eax, eax jnz display_number.do_div mov [bufLen], ecx ; store length of number .unstack: pop rdx mov [buf + ebx], dl ; ebx offset into buf, ecx is the digit count inc ebx dec ecx test ecx, ecx jnz display_number.unstack ; basicly a inline put_string(...) .write_number: mov eax, 1 ; sys_write(uint64_t fd, char *buf, size_t count) mov edi, 1 ; uint64 fd, 1 = STDOUT lea rsi, [buf] ; const char *buf mov edx, [bufLen] ; size_t count syscall ret wait_and_exit: lea rdi, [buf] ; char *buf mov esi, dword [bufLen] ; size_t count call read_input mov eax, 60 ; sys_exit mov edi, 0 ; int error_code syscall ; read_input(char *buf, size_t count) read_input: push rcx ;rcx and r11 are clobbered in syscalls push r11 mov rdx, rsi ; second arg to 3rd syscall arg mov rsi, rdi ; first arg to 2nd syscall arg xor rdi, rdi ; 0 = STDIN, 1st syscall arg mov eax, 0 ; sys_read(uint64 fd, char *buf, size_t count) syscall pop r11 pop rcx ret ; put_string(char *buf, size_t count) put_string: push rcx ;rcx and r11 are clobbered in syscalls push r11 mov rdx, rsi ; second arg to 3rd syscall arg mov rsi, rdi ; first arg to 2nd syscall arg mov edi, 1 ; 1 = STDOUT, 1st syscall arg mov eax, 1 ; sys_write(uint64 fd, char *buf, size_t count) syscall pop r11 pop rcx ret ; done to use rip relative addressing in_text_data: div_base3: dd 3h div_base5: dd 5h base10: dd 0Ah newline: db 0Ah
Become a Patron
Sponsor on GitHub
Donate via PayPal
Compiler Explorer Shop
Source on GitHub
Mailing list
Installed libraries
Wiki
Report an issue
How it works
Contact the author
CE on Mastodon
CE on Bluesky
Statistics
Changelog
Version tree