0

I'm (still) making my way through some of the bit hacks, and doing it all in assembly, for example from a previous question, Check if a number is even.

Here is what I have for toggling a bit:

toggle_bit:
    # NUM XOR (1 <<POS), pos is 1-indexed
    # Note: 
    #  NUM xor 0 = NUM
    #  NUM xor 1 = not(NUM), i.e., flip all bits
    mov $1, %eax        # the bit to shift (pos-1)
    lea -1(%esi), %ecx  # shift amount -- pos-1
    shl %cl, %rax       # now we have the 1 at the correct bit position
    xor %rdi, %rax
    ret

And called as:

mov $0b101, %edi # (5)
mov $2, %esi     # (toggle 2nd bit)
call toggle_bit  # return 0b111 (7)

Is this the suggested way to toggle a bit? Or should I be using the btc instruction?


Update: here is my improved function using btc:

toggle_bit:
    mov %rdi, %rax  # move the num into the return register
    dec %sil        # so pos it's one-indexed
    btc %rsi, %rax
    ret

It's one instruction shorter than the first way -- is one way 'better' than the other. If so, why?

David542
  • 104,438
  • 178
  • 489
  • 842
  • 1
    Does this answer your question? [Complementing ith bit](https://stackoverflow.com/questions/32680998/complementing-ith-bit) (which mentions that `btc` is good if both operands are registers) – harold Oct 03 '20 at 02:23
  • [gcc likes btc](https://gcc.godbolt.org/z/3TWcae). – Raymond Chen Oct 03 '20 at 02:24
  • @harold I added an update since I asked. Is one way preferred over the other then? – David542 Oct 03 '20 at 02:26
  • @RaymondChen thanks, yea I just ran it through Compiler Explorer and posted an update after getting a helper from that. – David542 Oct 03 '20 at 02:27
  • Apart from using `btc`, the most obvious improvement would be to stop using this weird 1-indexed bit position crap that forces you to `dec` the input. shift and bit-scan instructions (like `bsf` and `bsr`) all use 0-indexed bit position: the first bit is bit #0. And of course it never makes sense to wrap this in a function call, just inline a `btc` instruction, or if the bit-position is a known constant, an xor-immediate. – Peter Cordes Oct 03 '20 at 03:02

0 Answers0