Insert an `__asm__` block to do a addition in very large numbers

127 Views Asked by At

I am doing a program, and at this point I need to make it efficient. I am using a Haswell microarchitecture (64bits) and the 'g++'. The objective is made use of an ADC instruction, until the loop ends.

//I removed every carry handlers from this preview, yo be more simple
size_t anum = ap[i], bnum = bp[i];
unsigned carry;

// The Carry flag is set here with an common addtion  
anum += bnum;
cnum[0]= anum;
carry = check_Carry(anum, bnum);

for (int i=1; i<n; i++){

    anum  = ap[i];
    bnum = bp[i];

    //I want to remove this line and insert the __asm__ block
    anum += (bnum + carry);
    carry = check_Carry(anum, bnum);

    //This block is not working
    __asm__(
            "movq   -64(%rbp), %rcx;"
            "adcq   %rdx, %rcx;"
            "movq   %rsi, -88(%rbp);"
    );

    cnum[i] = anum;
}

Is the CF set only in the first addition? Or is it every time I do an ADC instruction?

I think that the problem is on the loss of the CF, every time the loop is done. If it is this the problem how I can solve it?

1

There are 1 best solutions below

11
On BEST ANSWER

You use asm like this in the gcc family of compilers:

 int src = 1;
 int dst;

 asm ("mov %1, %0\n\t"
     "add $1, %0"
     : "=r" (dst)
     : "r" (src));

 printf("%d\n", dst);

That is, you can refer to variables, rather than guessing where they might be in memory/registers.

[Edit] On the subject of carries: It's not completely clear what you are wanting, but: ADC takes the CF as an input and produces it as an output. However, MANY other instructions muck with the flags, (such as likely those used by the compiler to construct your for-loop), so you probably need to use some instructions to save/restore the CF (perhaps LAHF/SAHF).