ARM 7 汇编 - 立即数为 0 的 ADC

ARM 7 Assembly - ADC with immediate 0

我在 godbolt.org 上写了一个小的 c++ 函数,我对程序集中的某行感到好奇。这是函数:

unsigned long long foo(uint64_t a, uint8_t b){
    // unsigned long long fifteen = 15 * b;
    // unsigned long long result  = a + fifteen;
    // unsigned long long resultfinal = result / 2;
    // return resultfinal;

    return (a+(15*b)) / 2;
}

生成的程序集:

rsb     r2, r2, r2, lsl #4
adds    r0, r2, r0
adc     r1, r1, #0
lsrs    r1, r1, #1
rrx     r0, r0

现在我不明白为什么会出现带有ADC指令的那一行。它将 0 添加到 64 位数字的高位。为什么要这样做?

这里是link如果你想自己玩: Link to assembly

arm32只有32位。值 'a' 是 64 位。您看到的指令是允许计算大于 32 位的大小。

rsb     r2, r2, r2, lsl #4   # 15*b -> b*16-b
adds    r0, r2, r0           # a+(15*b) !LOW 32 bits! could carry.
adc     r1, r1, #0           # add a carry bit to the high portion
lsrs    r1, r1, #1           # divide high part by 2; (a+(15*b))/2
rrx     r0, r0               # The opposite of add with carry flowing down.

注意:如果你被adc指令搞糊涂了,那么rrx也会搞糊涂吗?它是 'dual' 的 addition/multiplication。对于除法,您需要处理较高部分的 underflow 并将其放在下一个较低的值中。


我认为重要的一点是你可以'carry'这个逻辑到任意大的值。它在密码学、大额金融和其他高精度科学和工程应用中都有应用。

参见:Gnu Multi-precision library, libtommath,等等