diff options
author | Rangi <remy.oukaour+rangi42@gmail.com> | 2021-07-31 21:12:34 -0400 |
---|---|---|
committer | Rangi <remy.oukaour+rangi42@gmail.com> | 2021-07-31 21:17:18 -0400 |
commit | 9d2e30aa7060240475a509c566ec20b9acccdffa (patch) | |
tree | 1d215d917d03596237891b94fb876b1c138d19e8 | |
parent | f2c5bbdc375cdbb759d4730e1d763fbf9ed12572 (diff) |
XOR swap
-rw-r--r-- | Optimizing-assembly-code.md | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/Optimizing-assembly-code.md b/Optimizing-assembly-code.md index 017085e..5ed248a 100644 --- a/Optimizing-assembly-code.md +++ b/Optimizing-assembly-code.md @@ -26,6 +26,7 @@ WikiTI's advice fully applies here: - [Set `a` to some constant minus `a`](#set-a-to-some-constant-minus-a) - [Set `a` to one constant or another depending on the carry flag](#set-a-to-one-constant-or-another-depending-on-the-carry-flag) - [Increment or decrement `a` when the carry flag is set](#increment-or-decrement-a-when-the-carry-flag-is-set) + - [Toggle `a` between two different constants](#toggle-a-between-two-different-constants) - [Divide `a` by 8 (shift `a` right 3 bits)](#divide-a-by-8-shift-a-right-3-bits) - [Divide `a` by 16 (shift `a` right 4 bits)](#divide-a-by-16-shift-a-right-4-bits) - [Set `a` to some value plus or minus carry](#set-a-to-some-value-plus-or-minus-carry) @@ -555,6 +556,49 @@ Instead, do this: ``` +### Toggle `a` between two different constants + +Don't do this: + +```asm + ; 12 bytes, 9 or 10 cycles + cp FOO + jr z, .foo_to_bar + jr .bar_to_foo +.foo_to_bar + ld a, BAR + jr .done +.bar_to_foo + ld a, FOO +.done + ... +``` + +And don't do this: + +```asm + ; 10 bytes, 7 or 9 cycles + cp FOO + jr z, .foo_to_bar ; nor jr nz, .bar_to_foo + ld a, FOO ; nor ld a, BAR + jr .done +.foo_to_bar ; nor .bar_to_foo + ld a, BAR ; nor ld a, FOO +.done + ... +``` + +(That would be applying the "[Conditional fallthrough](#conditional-fallthrough)" optimization to the first way.) + +Instead, do this: + +```asm + xor FOO ^ BAR ; 2 bytes, 2 cycles +``` + +(This works for the same reason as the [XOR swap algorithm](https://en.wikipedia.org/wiki/XOR_swap_algorithm) for swapping the values of two variables.) + + ### Divide `a` by 8 (shift `a` right 3 bits) Don't do this: |