From: Sam Moore Date: Fri, 4 Jul 2014 13:08:35 +0000 (+0800) Subject: Arbitrary integer addition in x64 assembly X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=commitdiff_plain;h=6ac558fc3f84dd6ecce1e4cd1094b090b205159c Arbitrary integer addition in x64 assembly Who needs portability? Also yes I could probably just use a library but that seems like cheating. --- diff --git a/src/tests/add_digits.s b/src/tests/add_digits.s new file mode 100644 index 0000000..09d4ea3 --- /dev/null +++ b/src/tests/add_digits.s @@ -0,0 +1,42 @@ +.section .text +.globl add_digits +.type add_digits, @function + +# Add two arrays of 64 bit digits, with carry, modifying the first argument +# Address at first argument %rdi is array to add and modify +# Address at second %rsi will be added (not modified) +# Third argument is counter of number of digits +# Result in %rax is the final result in the carry flag +# Exploits the fact that inc and dec do not affect the carry flag +add_digits: + loop: + movq (%rsi), %rax # Temporarily store digit from second array + adcq %rax, (%rdi) # Add digits in second and first array, store in first + dec %rdx # Decrement counter + jz end_loop # We are done + + # Move to next element in the first array + inc %rdi + inc %rdi + inc %rdi + inc %rdi + inc %rdi + inc %rdi + inc %rdi + inc %rdi + # Move to next element in the second array + inc %rsi + inc %rsi + inc %rsi + inc %rsi + inc %rsi + inc %rsi + inc %rsi + inc %rsi + jmp loop # Repeat + end_loop: + movq $0, %rax + jnc end + movq $1, %rax + end: + ret # We are done diff --git a/src/tests/add_digits_test.c b/src/tests/add_digits_test.c new file mode 100644 index 0000000..7bf385a --- /dev/null +++ b/src/tests/add_digits_test.c @@ -0,0 +1,39 @@ +/** + * Compile and linking: + * gcc -c add_digits.s + * gcc -c add_digits_test.c + * gcc -o add_digits_test add_digits_test.o add_digits.o + */ + +//TODO: Move to C++ + +#include +#include + +int64_t add_digit(int64_t * a, int64_t * b); + +int main(int argc, char ** argv) +{ + int64_t s1[] = {5,6,7,0xFFFFFFFFFFFFFFFF,0}; + int64_t s2[] = {7,1,5,1L,0}; + + int size = sizeof(s1)/sizeof(int64_t); + + printf("Before adding s1 and s2:\n"); + int i; + for (i = 0; i < size; ++i) + { + printf("s1[%d] = %.16lx\t", i, s1[i]); + printf("s2[%d] = %.16lx\n", i, s2[i]); + } + + add_digits(s1, s2, size); + printf("\nAfter adding s1 and s2:\n"); + for (i = 0; i < size; ++i) + { + printf("s1[%d] = %.16lx\t", i, s1[i]); + printf("s2[%d] = %.16lx\n", i, s2[i]); + } + + +}