【发布时间】:2024-04-24 13:20:01
【问题描述】:
是的,谢谢,它有效。 @彼得科德斯。 __int128 也有效。但是,正如您所说的另一件事,使用 C 中 _addcarry_u64 的多精度算术的内在函数,使用头文件 immintrin.h 我有以下代码
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <immintrin.h>
unsigned char _addcarry_u64(unsigned char c_in, uint64_t src1, uint64_t src2,uint64_t *sum);
int main()
{
unsigned char carry;
uint64_t sum;
long long int c1=0,c2=0;
uint64_t a=0x0234BDFA12CD4379,b=0xA8DB4567ACE92B38;
carry = _addcarry_u64(0,a,b,&sum);
printf("sum is %lx and carry value is %u n",sum,carry);
return 0;
}
你能指出错误吗?我收到了对_addcarry_u64 的未定义引用。一些快速的谷歌没有回答问题,如果要使用任何其他头文件或者它与 gcc 不兼容,为什么会这样
最初我有这段代码用于添加两个 64 位数字:
static __inline int is_digit_lessthan_ct(digit_t x, digit_t y)
{ // Is x < y?
return ( int)((x ^ ((x ^ y) | ((x - y) ^ y))) >> (RADIX-1));
}
#define ADDC(carryIn, addend1, addend2, carryOut, sumOut) \
{ digit_t tempReg = (addend1) + (int)(carryIn); \
(sumOut) = (addend2) + tempReg; \
(carryOut) = (is_digit_lessthan_ct(tempReg, (int)(carryIn)) | is_digit_lessthan_ct((sumOut), tempReg)); \
}
现在我知道使用汇编语言可以提高此实现的速度。因此,我正在尝试做类似的事情,但是我无法访问或归还进位。这是我的代码:
#include<stdio.h>
#include<stdlib.h>
#include<stdint.h>
uint64_t add32(uint64_t a,uint64_t b)
{
uint64_t d=0,carry=0;
__asm__("mov %1,%%rax\n\t"
"adc %2,%%rax\n\t"
"mov %%rax,%0\n\t"
:"=r"(d)
:"r"(a),"r"(b)
:"%rax"
);
return d;
}
int main()
{
uint64_t a=0xA234BDFA12CD4379,b=0xA8DB4567ACE92B38;
printf("Sum = %lx \n",add32(a,b));
return 0;
}
此加法的结果应该是 14B100361BFB66EB1,其中 msb 中的初始 1 是进位。我想将该进位保存在另一个寄存器中。我尝试了 jc,但我遇到了一些或其他错误。甚至 setc 也给了我错误,可能是因为我不确定语法。那么谁能告诉我如何将进位保存在另一个寄存器中或通过修改此代码返回它?
【问题讨论】:
-
你看过docs吗?
-
在较新版本的 GCC 上,您可以使用
"=@ccc"(carry)输出约束来获取进位标志的值并将其存储到carry变量中。或者,您可以使用扩展汇编模板中的setc指令将输出约束的值设置为进位标志的值。 -
或者您可以将
asm goto和jc转换为return 1;或直接转换为return 0;如果您在if()中使用它,这可以编译成好的代码。 -
顺便说一句,如果你的内联汇编中的第一条或最后一条指令是
mov,你通常做错了。告诉编译器您希望在与输入之一相同的寄存器中产生输出,或者使用"+r"读写操作数。见*.com/tags/inline-assembly/info。 -
@TanushreeBanerjee :当您添加
"=@ccc"(carry)约束时,您是否还通过调整参数来更改汇编器模板,因为它们不再是 %0、%1 和 %2。至少 %1 会变成 %2,而 %2 会变成 %3。如果您的某些参数通过插入新约束而偏离 1,我可以看到您在汇编器模板中出现错误。
标签: c assembly 64-bit addition