dimanche 1 mars 2015

how can I guarantee 32-bit unsigned addition on an x64 processor using GCC inline assembly?


I'm implementing an algorithm to add big integers using the carry flag, and it has become useful to me to think of these integers as digits in base 2^32. My question is, how/can I guarantee that my inline assembler code is adding these digits as 32-bit integers and processing the carry bit, as opposed to leaving the carry bit in the unused half of a 64-bit integer?


As far as I can tell, the best way to instruct the assembler to use 32-bit instructions is by using the 'l' suffix after 'adcx' and 'mov' instructions. Is this sufficient to guarantee 32-bit operation?



uint32_t* add(uint32_t *lhs, uint32_t *rhs, size_t length)
{
volatile uint32_t *result = (uint32_t*) malloc((inLen + 1)*sizeof(uint32_t));
++inLen;
for(size_t i=0; i<length;++i)
{
result[i] = 0;
}
asm volatile( "movq $0,%%rax\n\t"
"clc\n\t"
"pushf\n\t"
"0:\n\t"
"movq $0,%%rcx\n\t"
"adcxl (%2,%%rax,4),%%ecx\n\t"
"popf\n\t"
"adcxl (%3,%%rax,4),%%ecx\n\t"
"pushf\n\t"
"movl %%ecx,(%1,%%rax,4)\n\t"
"inc %%rax\n\t"
"cmp %%rax,%4\n\t"
"jnz 0b\n\t"
"popf\n\t"
: "=r"(result)
: "0"(result), "r"(lhs), "r"(rhs), "r"(length)
: "%rax","%rcx","cc");
return result;
}



Aucun commentaire:

Enregistrer un commentaire