summaryrefslogtreecommitdiff
path: root/assembler/gcd-x86_64-linux.s
diff options
context:
space:
mode:
Diffstat (limited to 'assembler/gcd-x86_64-linux.s')
-rw-r--r--assembler/gcd-x86_64-linux.s126
1 files changed, 0 insertions, 126 deletions
diff --git a/assembler/gcd-x86_64-linux.s b/assembler/gcd-x86_64-linux.s
deleted file mode 100644
index ad92477..0000000
--- a/assembler/gcd-x86_64-linux.s
+++ /dev/null
@@ -1,126 +0,0 @@
-# This program is for Linux on Intel x86_64 arch (64 bits).
-# Written for GNU Assembler (as) with AT&T syntax
-
-# To make an executable binary:
-# gcc -nostdlib gcd-x86_64-linux.s -o gcd-x86_64-linux
-# or
-# as gcd-x86_64-linux.s -o gcd-x86_64-linux.o && \
-# ld gcd-x86_64-linux.o -o gcd-x86_64-linux
-
-
-.data
-
-# Buffer for output:
-buffer:
- .space 64 # enough for 64 bits integer
-buf_end:
- .byte 10 # new line
-
-
-.text
-.globl _start
-
-
-# GCD of two numbers.
-# input: rax, rbx - two numbers
-# output: rax - GCD
-# uses: rax, rbx, rdx
-gcd2:
- and %rbx, %rbx # is %rbx == 0 ?
- jz gcd2_exit # %rbx == 0, go to exit and return %rax (GCD)
- xor %rdx, %rdx # set %rdx = 0 */
- div %rbx # divide: %rdx:%rax / %rbx, actually: %rax / %rbx
- mov %rbx, %rax # drop quotient in %rax and keep prrvious %rbx in %rax
- mov %rdx, %rbx # put remainder in %rbx
- jmp gcd2
-gcd2_exit:
- ret
-
-
-
-# Print an unsigned integer in rax.
-# input: rax - unsigned integer to print
-# uses: rax, rbx, rcx, rdx, rdi, buffer
-print:
- mov $10, %rcx # set %rcx = 10 (radix)
- mov $buf_end, %rsi
-
-next_digit:
- xor %rdx, %rdx # set %rdx = 0
- div %rcx # divide: %rdx:%rax / %rcx, actually: %rax / %rcx
- # %rdx is a remainder (0-9), it fits into %dl
- add $48, %dl # get ASCII code: 0 => 48 = '0', 1 => 49 = '1'
- dec %rsi # put remainders going from the end of the buffer
- mov %dl, (%rsi)
- # now rax is a quotient
- and %rax, %rax # is quotient == 0 ?
- jnz next_digit # quotient is not 0, go on
-
- # printing the number:
- mov $1, %rax # syscall `write'
- mov $1, %rdi # write to stdout
- mov $buf_end, %rdx
- sub %rsi, %rdx # rdx is a number of characters to write (buf_end - rsi)
- inc %rdx # + new line
- syscall # do syscall (print the number at rsi)
-
- ret
-
-
-# Convert string into unsigned integer
-# input: rsi - pointer to string
-# output: rbx - unsigned integer
-# uses: rax, rbx, rcx, rdi, direction flag
-str2uint:
- xor %rcx, %rcx # it will be the string length
- dec %rcx # rcx = -1 != 0 for repne
- xor %rax, %rax # search for 0 (%rax = %al = 0)
- mov %rsi, %rdi
- cld # Search forward (std - backward)
- repne scasb # search for 0 (in %al), incrementing rdi, decrementing rcx
- not %rcx # invert rcx to have the string length
- dec %rcx # minus ending zero
-
- xor %rbx, %rbx
-str2uint_loop:
- lodsb # going forward from rsi
- # HINT: assert '0' <= al <= '9'
- lea (%rbx, %rbx, 4), %rbx # rbx = 4*rbx + rbx = 5*rbx ;-)
- lea -48(%rax, %rbx, 2), %rbx # rbx = 2*rbx + %rax - 48
- # rbx is multiplied by 10 each iteration,
- # rax-48 will be multiplied at the next iteration ;-)
- loop str2uint_loop
- ret
-
-
-
-# Entry point for the program
-_start:
-
- # Access command line, see:
- # http://www.cin.ufpe.br/~if817/arquivos/asmtut/index.html
- # Example: ./gcd-x86_64-linux 11 22 33
- pop %rcx # Get the number of command-line options (4)
- pop %rsi # Get the pointer to the program name (./gcd-x86_64-linux),
- dec %rcx # minus program name
- jz exit # no arguments are given - exiting
-
- xor %rax, %rax
-gcd_loop:
- pop %rsi # get next command line argument
- mov %rcx, %r8 # save argument counter
- mov %rax, %r9 # save current GCD
- call str2uint # convert string at rsi to integer at rbx
- mov %r9, %rax # restore current GCD
- call gcd2 # gcd of rax and rbx (returned by str2uint)
- # now rax is a GCD
- mov %r8, %rcx # restore argument counter
- loop gcd_loop
-
- call print # print rax with GCD
-
-exit:
- mov $60, %rax # exit syscall
- xor %rdi, %rdi # exit code = 0
- syscall
-