diff --git a/contents/euclidean_algorithm/code/asm-x64/euclidean_example.s b/contents/euclidean_algorithm/code/asm-x64/euclidean_example.s new file mode 100644 index 000000000..c08bb0878 --- /dev/null +++ b/contents/euclidean_algorithm/code/asm-x64/euclidean_example.s @@ -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 diff --git a/contents/euclidean_algorithm/euclidean_algorithm.md b/contents/euclidean_algorithm/euclidean_algorithm.md index d105645ba..1de60f463 100644 --- a/contents/euclidean_algorithm/euclidean_algorithm.md +++ b/contents/euclidean_algorithm/euclidean_algorithm.md @@ -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" %} @@ -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" %} @@ -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" %}