Поскольку a + b
может быть расширен до (a ^ b) + ((a & b) << 1)
, если доступны +, -, &
-операторы, выполняется следующее:
a ^ b == a + b - (a & b) - (a & b)
.
Фактически gcc 8.2.1
оптимизирует следующую c-функцию
unsigned foo(unsigned a, unsigned b)
{
return a + b - (a & b) - (a & b);
}
до следующей сборки x86-64 с помощью -O3
:
foo:
movl %edi, %eax
xorl %esi, %eax
ret
Следовательно, ни инструкции перехода не требуются, ни болеетри регистра (далее псевдосборка):
$r1 = a //first argument
$r2 = b //second argument
$r3 = $r1 & $r2 //one temp register is enough
$r1 = $r1 + $r2
$r1 = $r1 - $r3
$r1 = $r1 - $r3 //$r1 is the return value