【问题标题】:Insert an `__asm__` block to do a addition in very large numbers插入一个 `__asm__` 块来做一个非常大的加法
【发布时间】:2016-02-05 15:21:25
【问题描述】:

我正在做一个程序,此时我需要让它高效。 我正在使用 Haswell 微架构(64 位)和“g++”。 目标是使用ADC 指令,直到循环结束。

//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;
}

CF 是否在第一次添加中设置only?还是每次我执行ADC 指令时都会这样?

我认为问题出在CFloss 上,每次循环 完成。如果是这个问题,我该如何解决?

【问题讨论】:

  • 那永远不会那样工作,进位标志可以在您到达那里时更改。如果你坚持要优化这个,你应该用纯 asm 编写整个循环,这样你就不必为 gcc 内联 asm 而烦恼,这是一个复杂的野兽。
  • 我所有的代码都不在这里。这只是主要的谷物。在我的代码中,我确实使用另一个局部变量进行控制,但我想删除它。
  • 代码到底应该做什么?对于循环的每次迭代,是否要使用第 2 行设置的相同 CF 值?如果是这样,您需要使用setc 指令或其他东西来保留标志的状态。请记住,大多数 x86 指令设置了标志,这会破坏标志的旧状态。
  • 如果您不想自己保存标志,唯一的方法是将整个东西放入 asm 中,这样您就可以确保 CF 没有被破坏。最好的办法就是把它放到一个单独的 asm 模块中。
  • 这段代码是做一个非常大的数字的加法。我想在每次迭代中使用最后一次加法的结果,以了解最后一次是否发生溢出。如果有指令可以破坏标志的旧状态,我如何确保不会发生这种情况? CF 不是在我每次执行“ADC”指令时设置的吗?如果是这样,我明白出了什么问题。

标签: c++ assembly cpu-registers bignum multiprecision


【解决方案1】:

您在 gcc 系列编译器中像这样使用asm

 int src = 1;
 int dst;

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

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

也就是说,您可以引用变量,而不是猜测它们在内存/寄存器中的位置。

[编辑] 关于携带的主题:尚不完全清楚您想要什么,但是:ADCCF 作为输入并将其作为输出产生。但是,许多其他指令都带有标志(例如编译器用来构造 for 循环的那些指令),因此您可能需要使用一些指令来保存/恢复 CF(可能是 LAHF/SAHF)。

【讨论】:

  • 我想知道为什么投反对票?似乎是一个有用的答案(除了缺少adc 的需要,这很容易修复)?...
  • 虽然它确实指向了正确的方向,但它并没有回答问题并且过度简化了事情。可能只是一条评论说 gcc asm 块使用约束来指定输入输出,并带有指向所述文档的链接。
  • 所以,包括一个例子 == 否决票。说得通。不是。
  • 包括一个内联汇编外观的一般示例,虽然没有解决任何特定问题,例如 CF 被其他编译器生成的代码破坏,但我确实获得了 -1。 PS:我们不需要在这里解释对 SO 的投反对票,我也不知道为什么其他人投反对票。
  • 我投了反对票,因为答案只解决了有关将变量传递到模板中的问题的一部分,但它并没有解决代码中更大的问题——关于 CF 标志的问题.后者涉及更多,并且未包含在您的答案中。
猜你喜欢
  • 1970-01-01
  • 2013-07-07
  • 1970-01-01
  • 2011-11-20
  • 2022-08-19
  • 1970-01-01
  • 1970-01-01
  • 2015-05-18
  • 2016-04-23
相关资源
最近更新 更多