Skip to content

Adding Euclidean Algorithms in X86-64 Assembly #367

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Oct 16, 2018
74 changes: 74 additions & 0 deletions contents/euclidean_algorithm/code/asm-x64/euclidean_example.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
.intel_syntax noprefix

.section .rodata
fmt: .string "%d\n"

.section .text
.global main
.extern printf

# rdi - a
# rsi - b
# RET rax - gcd of a and b
euclid_mod:
mov rax, rdi # Get abs of a
sar rax, 31
xor rdi, rax
sub rdi, rax
mov rax, rsi # Get abs of b
sar rax, 31
xor rsi, rax
sub rsi, rax
jmp mod_check
mod_loop:
xor rdx, rdx # Take the mod of a and b
mov rax, rdi
div rsi
mov rdi, rsi # Set b to the mod of a and b
mov rsi, rdx # Set a to b
mod_check:
cmp rsi, 0 # Check if b is non-zero
jne mod_loop
mov rax, rdi # Return the result
ret

euclid_sub:
mov rax, rdi # Get abs of a
sar rax, 31
xor rdi, rax
sub rdi, rax
mov rax, rsi # Get abs of b
sar rax, 31
xor rsi, rax
sub rsi, rax
jmp check
loop:
cmp rdi, rsi # Find which is bigger
jle if_true
sub rdi, rsi # If a is bigger then a -= b
jmp check
if_true:
sub rsi, rdi # Else b -= a
check:
cmp rsi, rdi # Check if a and b are not equal
jne loop
mov rax, rdi # Return results
ret

main:
mov rdi, 4288 # Call euclid_mod
mov rsi, 5184
call euclid_mod
mov rdi, OFFSET fmt # Print output
mov rsi, rax
xor rax, rax
call printf
mov rdi, 1536 # Call euclid_sub
mov rsi, 9856
call euclid_sub
mov rdi, OFFSET fmt # Print output
mov rsi, rax
xor rax, rax
call printf
xor rax, rax # Return 0
ret
6 changes: 6 additions & 0 deletions contents/euclidean_algorithm/euclidean_algorithm.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ The algorithm is a simple way to find the *greatest common divisor* (GCD) of two
[import:12-25, lang="julia"](code/julia/euclidean.jl)
{% sample lang="nim" %}
[import:13-24, lang="nim"](code/nim/euclid_algorithm.nim)
{% sample lang="asm-x64" %}
[import:43-78, lang="asm-x64"](code/asm-x64/euclidean_example.s)
{% sample lang="f90" %}
[import:1-19, lang="fortran"](code/fortran/euclidean.f90)
{% sample lang="scala" %}
Expand Down Expand Up @@ -94,6 +96,8 @@ Modern implementations, though, often use the modulus operator (%) like so
[import:1-10, lang="julia"](code/julia/euclidean.jl)
{% sample lang="nim" %}
[import:1-11, lang="nim"](code/nim/euclid_algorithm.nim)
{% sample lang="asm-x64" %}
[import:8-41, lang="asm-x64"](code/asm-x64/euclidean_example.s)
{% sample lang="f90" %}
[import:21-34, lang="fortran"](code/fortran/euclidean.f90)
{% sample lang="scala" %}
Expand Down Expand Up @@ -154,6 +158,8 @@ The Euclidean Algorithm is truly fundamental to many other algorithms throughout
[import, lang="julia"](code/julia/euclidean.jl)
{% sample lang="nim" %}
[import, lang="nim" %](code/nim/euclid_algorithm.nim)
{% sample lang="asm-x64" %}
[import, lang="asm-x64"](code/asm-x64/euclidean_example.s)
{% sample lang="f90" %}
[import, lang="fortran"](code/fortran/euclidean.f90)
{% sample lang="scala" %}
Expand Down