summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Optimizing-assembly-code.md56
1 files changed, 24 insertions, 32 deletions
diff --git a/Optimizing-assembly-code.md b/Optimizing-assembly-code.md
index c55d8fd..107dbd9 100644
--- a/Optimizing-assembly-code.md
+++ b/Optimizing-assembly-code.md
@@ -19,7 +19,7 @@ WikiTI's advice fully applies here:
- [Set `a` to 0](#set-a-to-0)
- [Invert the bits of `a`](#invert-the-bits-of-a)
- [Set `a` to some constant minus `a`](#set-a-to-some-constant-minus-a)
- - [Set `a` to one constant or another depending on carry](set-a-to-one-constant-or-another-depending-on-carry)
+ - [Set `a` to one constant or another depending on the carry flag](#set-a-to-one-constant-or-another-depending-on-the-carry-flag)
- [Multiply `hl` by 2](#multiply-hl-by-2)
- [Add `a` to a 16-bit register](#add-a-to-a-16-bit-register)
- [Add `a` to an address](#add-a-to-an-address)
@@ -71,9 +71,9 @@ Don't use the optimized versions if you need to preserve flags. As such, `ld a,
```asm
ld a, [wIsTrainerBattle]
- and a ; NZ if [wIsTrainerBattle] is nonzero
- ld a, 0
- jr nz, .trainer
+ and a ; sets flag Z if [wIsTrainerBattle] is 0
+ ld a, 0 ; sets a to 0 without affecting Z
+ jr nz, .is_trainer_battle
```
@@ -112,15 +112,17 @@ But do:
```
-### Set `a` to one constant or another depending on carry
+### Set `a` to one constant or another depending on the carry flag
+
+(The example sets `a` to `ONE` if the carry flag is set (`c`), or `TWO` is the carry flag is not set (`nc`).)
Don't do:
```asm
; 6 bytes, 6 or 7 cycles
- ld a, CONST
+ ld a, ONE
jr c, .carry
- ld a, 0
+ ld a, TWO
.carry
```
@@ -128,48 +130,38 @@ And don't do:
```asm
; 6 bytes, 6 or 7 cycles
- ld a, 0
+ ld a, TWO
jr nc, .no_carry
- ld a, CONST
+ ld a, ONE
.no_carry
```
But do:
```asm
- ; 3 bytes, 3 cycles
- sbc a
- and CONST
+ ; 5 bytes, 5 cycles
+ sbc a ; if carry, then $ff, else 0
+ and ONE ^ TWO ; $ff becomes ONE ^ TWO, 0 stays 0
+ xor TWO ; ONE ^ TWO becomes ONE, 0 becomes TWO
```
-Likewise, don't do:
+If `ONE` is 0 (i.e. set `a` to 0 if carry), then do:
```asm
- ; 6 bytes, 6 or 7 cycles
- ld a, 0
- jr c, .carry
- ld a, CONST
-.carry
+ ; 4 bytes, 4 cycles
+ ccf ; invert carry flag
+ sbc a ; if originally carry, then 0, else $ff
+ and TWO ; 0 stays 0, $ff becomes TWO
```
-And don't do:
+If `TWO` is 0 (i.e. set `a` to 0 if not carry), then do:
```asm
- ; 6 bytes, 6 or 7 cycles
- ld a, CONST
- jr nc, .no_carry
- ld a, 0
-.no_carry
+ ; 3 bytes, 3 cycles
+ sbc a ; if carry, then $ff, else 0
+ and ONE ; $ff becomes ONE, 0 stays 0
```
-But do:
-
-```asm
- ; 4 bytes, 4 cycles
- ccf
- sbc a
- xor CONST
-```
### Multiply `hl` by 2