I'm writing a program in NASM for Intel 80386 processor and i need to set the value of carry flag in a specific bit in GPR (general purpose register) without changing other bits in register.
Are there any possibility of doing so without using shifts/rotations of any kind?
One branch-free way of doing this would be to fill a scratch register with the carry flag, mask for the bit you want, then or it with your target register.
Using
EAX
as scratch (taking this as 32-bit values being manipulated):If the carry flag is unset,
sbb
will doeax = eax - eax = 0
. If the carry flag is set,sbb
will doeax = eax - (eax + 1) = -1
, so all bits are set. The desired bit(s) is/are then masked in.After that, you need to set the appropriate bit(s) in the target. If the bit is in an initial known state, this could be simplified. Using
EBX
as target:Depending on what previously happened to the scratch register (
EAX
here) it might be worth looking at some optimization information like https://www.agner.org/optimize/. Some processors will recognize that the new value ofEAX
doesn't depend on the old value, some will see it as having a (false) dependency on that old value.After looking at it, the document "Optimizing subroutines in assembly language" mentions the above
sbb
trick in the section "Replacing conditional jumps with bit-manipulation instructions".Using
EAX
(the accumulator) as the scratch register will result in smaller code size.