Язык C ++ не имеет никакого понятия флага переноса, поэтому создание встроенной функции-оболочки вокруг инструкции ADC
неуклюже. Однако Intel все равно это сделала: unsigned char _addcarry_u32 (unsigned char c_in, unsigned a, unsigned b, unsigned * out);
. В последний раз, когда я проверял, gcc справился с этим плохо (сохранив результат переноса в целочисленный регистр вместо того, чтобы оставить его в CF), но, надеюсь, собственный компилятор Intel справится с этим лучше.
См. Также вики-тег x86 для документации по сборке.
Компилятор будет использовать для вас ADC при добавлении целых чисел, превышающих один регистр, например добавление int64_t
в 32-битном коде или __int128_t
в 64-битном коде.
#include <stdint.h>
#ifdef __x86_64__
__int128_t add128(__int128_t a, __int128_t b) { return a+b; }
#endif
# clang 3.8 -O3 for x86-64, SystemV ABI.
# __int128_t args passed in 2 regs each, and returned in rdx:rax
add rdi, rdx
adc rsi, rcx
mov rax, rdi
mov rdx, rsi
ret
вывод asm из проводника компилятора Godbolt . -fverbose-asm
от clang не очень вежливый, но gcc 5.3 / 6.1 тратит впустую две mov
инструкции, поэтому он менее читабелен.