2

I was wondering if there was a way to toggle the low order bit in binary.
For example:
01000001 -> Toggle Low Order Bit -> 01000000
Changing the last bit on the right only.
If you are unfamiliar with LC3 it only has the following operations:

  • ADD

  • AND

  • NOT
Jacob
  • 113
  • 1
  • 10
  • Could you just AND RESULT, BITS, xFFFE ? – Jacob Nov 21 '17 at 04:37
  • `and` will clear the bits, not toggle – phuclv Nov 21 '17 at 04:47
  • 2
    boolean alegebra tells us: `a XOR b` := `(a AND (NOT b)) OR ((NOT a) AND b)` ( one of the bits is 1, and the other one 0) – Tommylee2k Nov 21 '17 at 07:36
  • 2
    That seems like a really annoying architecture to program on. You have to spend a bunch of time figuring out how to do basic boolean operations like `XOR` or `OR` as well as figuring out which bits to test and branch on. – Peter Cordes Nov 21 '17 at 11:06

2 Answers2

3

This would typically be accomplished with a XOR, operation.

; field is R0
; R1 is mask of bits to toggle
; R2 is scratch
LD R0, #0b01000001
LD R1, #0b00000001
NOT R2, R0
AND R2, R2, R1
NOT R1, R1
AND R0, R0, R1
ADD R0, R0, R2
; result in R0
Mitch
  • 21,223
  • 6
  • 63
  • 86
  • 1
    Your code works, but that's not [a bitwise NOR](https://en.wikipedia.org/wiki/NOR_logic). The overall operation is [an XOR](https://en.wikipedia.org/wiki/XOR_gate), so it flips every bit that's set in the mask. – Peter Cordes Nov 21 '17 at 11:14
  • @PeterCordes, True! I'm not sure why I said NOR. I was thinking XOR and even looking at an XOR truth table. – Mitch Nov 21 '17 at 22:52
1

If the lowest bit is 0, then you need to add 1.

If the lowest bit is 1, then you need to add -1.

So if input is a, then:

 x = a and 1    ; x = 0/1 depending on lowest bit
 x = x + x      ; x = 0/2
 x = not x      ; x = -1/-3
 x = x + 2      ; x = +1/-1
 r = a + x      ; will toggle lowest bit of original a

I assume the two's complement negative integer values is used in LC3, so NOT 2 == -3, and -1 + 2 = +1.

Unfortunately I don't know LC3, so I just hope my steps are reasonably simple to be implemented by LC3 instructions and the algorithm makes sense.


Other option is to use the NOT to toggle the bit (not addition):

 x = a and (not(1)) ; (0xFFFE in case of 16b word)
     ; x = copy of all bits of A except bottom bit (bottom bit = 0)
 y = not(a) and 1   ; extract toggled bottom bit (1/0)
 r = x + y          ; compose the value back from the upper:lowest bit(s)

edit: which is what Mitch does in his answer.

Ped7g
  • 16,236
  • 3
  • 26
  • 63
  • AFAIK, LC3's `add` instruction is unsigned binary (and thus also 2's complement signed). Any other signed number format would need a separate signed-add instruction. Or to put it another way, the number you need to add to clear the lowest bit if it's set is unsigned all-ones, like you get with C `unsigned`. – Peter Cordes Nov 21 '17 at 13:41
  • Using more constants may be a downside for LC3; I don't think it has immediate forms of anything. But you could write (`~0-1`) more easily as `~1`. That's @Mitch's implementation: ANDN both ways with a mask and ADD (as a replacement for OR) to bit-blend between `not(a)` and `a`. (Exactly like you would blend elements with SSE2 AND/ANDN/OR when PBLENDVB isn't available.) – Peter Cordes Nov 21 '17 at 13:46
  • @PeterCordes yes, Mitch implementation is spot on and there's nothing to add to it. I still believe my answer may add some more background to OP, how it works, plus the "add" way idea... The (~0-1) is silly, I don't even know if OP understands C syntax... probably `not(1)` would be best in terms of LC3 question, will edit it. – Ped7g Nov 21 '17 at 13:48
  • Yeah, upvoted for an explanation of why it works. I didn't really see exactly how Mitch's worked until reading yours. – Peter Cordes Nov 21 '17 at 13:51