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'这个逻辑到任意大的值。它在密码学、大额金融和其他高精度科学和工程应用中都有应用。
我在 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'这个逻辑到任意大的值。它在密码学、大额金融和其他高精度科学和工程应用中都有应用。