diff options
author | Rangi <remy.oukaour+rangi42@gmail.com> | 2021-06-20 11:39:01 -0400 |
---|---|---|
committer | Rangi <remy.oukaour+rangi42@gmail.com> | 2021-06-20 11:39:01 -0400 |
commit | ea46ba7f557877ddbda3d435ec904bc6ab6912f6 (patch) | |
tree | a2b356a7ec1b2b576ff85e4b98a0b18703e603b7 | |
parent | 8245ddd75ce153222a43d47d3611d8ffd98f93f1 (diff) |
Rephrase guidelines
-rw-r--r-- | Optimizing-assembly-code.md | 328 |
1 files changed, 182 insertions, 146 deletions
diff --git a/Optimizing-assembly-code.md b/Optimizing-assembly-code.md index 9d27bde..ad09f33 100644 --- a/Optimizing-assembly-code.md +++ b/Optimizing-assembly-code.md @@ -72,19 +72,19 @@ WikiTI's advice fully applies here: ### Set `a` to 0 -Don't do: +Don't do this: ```asm - ld a, 0 ; 2 bytes, 2 cycles, no changes to flags + ld a, 0 ; 2 bytes, 2 cycles; no changes to flags ``` -But do: +Instead, do this: ```asm xor a ; 1 byte, 1 cycle, sets flags C to 0 and Z to 1 ``` -Or do: +Or do this: ```asm sub a ; 1 byte, 1 cycle, sets flags C to 0 and Z to 1 @@ -103,7 +103,7 @@ Don't use the optimized versions if you need to preserve flags. As such, `ld a, ### Increment or decrement `a` -When possible, avoid doing: +When possible, avoid doing this: ```asm add 1 ; 2 bytes, 2 cycles; sets carry for -1 to 0 overflow @@ -113,7 +113,7 @@ When possible, avoid doing: sub 1 ; 2 bytes, 2 cycles; sets carry for 0 to -1 underflow ``` -If you don't need to set the carry flag, then do: +If you don't need to set the carry flag, then do this: ```asm inc a ; 1 byte, 1 cycle @@ -126,13 +126,13 @@ If you don't need to set the carry flag, then do: ### Invert the bits of `a` -Don't do: +Don't do this: ```asm xor $ff ; 2 bytes, 2 cycles ``` -But do: +Instead, do this: ```asm cpl ; 1 byte, 1 cycle @@ -141,7 +141,7 @@ But do: ### Rotate the bits of `a` -Don't do: +Don't do this: ```asm rl a ; 2 bytes, 2 cycles; updates Z and C flags @@ -159,7 +159,7 @@ Don't do: rrc a ; 2 bytes, 2 cycles; updates Z and C flags ``` -But do: +Instead, do this: ```asm rla ; 1 byte, 1 cycle; updates C flag @@ -186,7 +186,7 @@ The exception is if you need to set the zero flag when the operation results in (The example uses `b` and `c`, but any of `d`, `e`, `h`, or `l` would also work.) -Don't do: +Don't do this: ```asm ; 26 bytes, 26 cycles @@ -197,7 +197,7 @@ endr ld a, b ``` -And don't do: +And don't do this: ```asm ; 17 bytes, 17 cycles @@ -217,7 +217,7 @@ And don't do: xor b ``` -But do: +Instead, do this: ```asm ; 15 bytes, 15 cycles @@ -235,7 +235,7 @@ But do: rrca ``` -Or if you really want to optimize for size over speed, then don't do: +Or if you really want to optimize for size over speed, then don't do this: ```asm ; 10 bytes, 59 cycles @@ -248,7 +248,7 @@ Or if you really want to optimize for size over speed, then don't do: ld a, b ``` -But do: +Instead, do this: ```asm ; 8 bytes, 50 cycles @@ -260,7 +260,7 @@ But do: ld a, b ``` -Or if you really want to optimize for speed over size, then do: +Or if you really want to optimize for speed over size, then do this: ```asm ; 6 bytes, 12 cycles @@ -287,7 +287,7 @@ endr ### Set `a` to some constant minus `a` -Don't do: +Don't do this: ```asm ; 4 bytes, 4 cycles @@ -296,7 +296,7 @@ Don't do: sub b ``` -But do: +Instead, do this: ```asm ; 3 bytes, 3 cycles @@ -311,7 +311,7 @@ But do: (The example sets `a` to `CVAL` if the carry flag is set (`c`), or `NCVAL` is the carry flag is not set (`nc`).) -Don't do: +Don't do this: ```asm ; 6 bytes, 6 or 7 cycles @@ -321,7 +321,7 @@ Don't do: .carry ``` -And don't do: +And don't do this: ```asm ; 6 bytes, 6 or 7 cycles @@ -331,7 +331,7 @@ And don't do: .no_carry ``` -And if either is 0, don't do: +And if either is 0, don't do this: ```asm ; 5 bytes, 5 cycles @@ -341,7 +341,7 @@ And if either is 0, don't do: .carry ``` -And if either is 1 more or less than the other, don't do: +And if either is 1 more or less than the other, don't do this: ```asm ; 5 bytes, 5 cycles @@ -351,7 +351,7 @@ And if either is 1 more or less than the other, don't do: .carry ``` -Instead use `sbc a`, which copies the carry flag to all bits of `a`. Thus do: +Instead use `sbc a`, which copies the carry flag to all bits of `a`. So do this: ```asm ; 5 bytes, 5 cycles @@ -360,7 +360,7 @@ Instead use `sbc a`, which copies the carry flag to all bits of `a`. Thus do: add NCVAL ; CVAL - NCVAL becomes CVAL, 0 becomes NCVAL ``` -Or do: +Or do this: ```asm ; 5 bytes, 5 cycles @@ -374,8 +374,8 @@ And if certain conditions apply, then do something more efficient: <table> <tr> -<th>If this...</th> -<th>...then do:</th> +<th>If this case...</th> +<th>...then do this:</th> </tr> <tr><td> @@ -530,7 +530,7 @@ And if certain conditions apply, then do something more efficient: ### Increment or decrement `a` when the carry flag is set -Don't do: +Don't do this: ```asm ; 3 bytes, 3 cycles @@ -546,7 +546,7 @@ Don't do: .ok ``` -But do: +Instead, do this: ```asm adc 0 ; 2 bytes, 2 cycles @@ -559,7 +559,7 @@ But do: ### Divide `a` by 8 (shift `a` right 3 bits) -Don't do: +Don't do this: ```asm ; 6 bytes, 9 cycles @@ -569,7 +569,7 @@ Don't do: ld a, b ; quotient ``` -And don't do: +And don't do this: ```asm ; 6 bytes, 6 cycles @@ -578,7 +578,7 @@ And don't do: srl a ``` -But do: +Instead, do this: ```asm ; 5 bytes, 5 cycles @@ -591,7 +591,7 @@ But do: ### Divide `a` by 16 (shift `a` right 4 bits) -Don't do: +Don't do this: ```asm ; 6 bytes, 9 cycles @@ -601,7 +601,7 @@ Don't do: ld a, b ; quotient ``` -And don't do: +And don't do this: ```asm ; 8 bytes, 8 cycles @@ -611,7 +611,7 @@ And don't do: srl a ``` -But do: +Instead, do this: ```asm ; 4 bytes, 4 cycles @@ -624,7 +624,7 @@ But do: (The example uses `b` and `c`, but any registers besides `a` would also work, including `[hl]`.) -Don't do: +Don't do this: ```asm ; 4 bytes, 4 cycles @@ -640,7 +640,7 @@ Don't do: sbc 0 ``` -And don't do: +And don't do this: ```asm ; 4 bytes, 4 cycles @@ -656,7 +656,7 @@ And don't do: sbc c ``` -But do: +Instead, do this: ```asm ; 3 bytes, 3 cycles @@ -672,7 +672,7 @@ But do: add b ``` -Also, don't do: +Also, don't do this: ```asm ; 5 bytes, 5 cycles @@ -688,7 +688,7 @@ Also, don't do: sbc 0 ``` -And don't do: +And don't do this: ```asm ; 5 bytes, 5 cycles @@ -704,7 +704,7 @@ And don't do: sbc N ``` -But do: +Instead, do this: ```asm ; 4 bytes, 4 cycles @@ -727,7 +727,7 @@ But do: (The example uses `b`, but any of `c`, `d`, `e`, `h`, or `l` would also work.) -Don't do: +Don't do this: ```asm ; 4 bytes, 4 cycles @@ -743,7 +743,7 @@ Don't do: ld b, a ``` -And don't do: +And don't do this: ```asm ; 4 bytes, 4 cycles @@ -759,7 +759,7 @@ And don't do: ld b, a ``` -But do: +Instead, do this: ```asm ; 3 bytes, 3 or 4 cycles @@ -778,7 +778,7 @@ But do: ### Load from HRAM to `a` or from `a` to HRAM -Don't do: +Don't do this: ```asm ld a, [hFoobar] ; 3 bytes, 4 cycles @@ -788,7 +788,7 @@ Don't do: ld [hFoobar], a ; 3 bytes, 4 cycles ``` -But do: +Instead, do this: ```asm ldh a, [hFoobar] ; 2 bytes, 3 cycles @@ -804,7 +804,7 @@ But do: ### Multiply `hl` by 2 -Don't do: +Don't do this: ```asm ; 4 bytes, 4 cycles @@ -812,7 +812,7 @@ Don't do: rl h ``` -But do: +Instead, do this: ```asm add hl, hl ; 1 byte, 2 cycles @@ -823,7 +823,7 @@ But do: (The example uses `hl`, but `bc` or `de` would also work.) -Don't do: +Don't do this: ```asm ; 6 bytes, 6 cycles @@ -834,7 +834,7 @@ Don't do: ld h, a ``` -and don't do: +And don't do this: ```asm ; 6 bytes, 6 cycles @@ -845,7 +845,7 @@ and don't do: ld h, a ``` -and don't do: +And don't do this: ```asm ; 5 bytes, 5 cycles @@ -856,10 +856,10 @@ and don't do: .no_carry ``` -But do: +Instead, do this: ```asm - ; 5 bytes, 5 cycles, no labels + ; 5 bytes, 5 cycles; no labels add l ld l, a adc h @@ -867,7 +867,7 @@ But do: ld h, a ``` -Or if you can spare another 16-bit register and want to optimize for size over speed, do: +Or if you can spare another 16-bit register and want to optimize for size over speed, then do this: ```asm ; 4 bytes, 5 cycles @@ -881,7 +881,7 @@ Or if you can spare another 16-bit register and want to optimize for size over s (The example uses `hl`, but `bc` or `de` would also work.) -Don't do: +Don't do this: ```asm ; 8 bytes, 8 cycles @@ -893,7 +893,7 @@ Don't do: ld h, a ``` -But do: +Instead, do this: ```asm ; 7 bytes, 7 or 8 cycles @@ -907,7 +907,7 @@ But do: (This is a case of "[Add or subtract the carry flag from a register besides `a`](#add-or-subtract-the-carry-flag-from-a-register-besides-a)", applied to the high part of a 16-bit register.) -Or if you can spare another 16-bit register, do: +Or if you can spare another 16-bit register, do this: ```asm ; 4 bytes, 5 cycles @@ -920,7 +920,7 @@ Or if you can spare another 16-bit register, do: (The example uses `hl`, but `bc` or `de` would also work.) -Don't do: +Don't do this: ```asm ; 7 bytes, 8 cycles; uses another 16-bit register @@ -930,7 +930,7 @@ Don't do: add hl, de ``` -And don't do: +And don't do this: ```asm ; 8 bytes, 8 cycles @@ -942,7 +942,7 @@ And don't do: ld h, a ``` -And don't do: +And don't do this: ```asm ; 8 bytes, 8 cycles @@ -954,7 +954,7 @@ And don't do: .no_carry ``` -But do: +Instead, do this: ```asm ; 7 bytes, 7 cycles @@ -965,7 +965,7 @@ But do: ld h, a ``` -And if the constant is 8-bit and nonzero (i.e. 0 < `FooBar` < 256), then do: +Or if the constant is 8-bit and nonzero (i.e. 0 < `FooBar` < 256), then do this: ```asm ; 6 bytes, 6 cycles @@ -976,7 +976,7 @@ And if the constant is 8-bit and nonzero (i.e. 0 < `FooBar` < 256), then do: ld h, a ``` -And if the constant is zero (i.e. `FooBar` == 0 and `a` + `FooBar` == `a`), then do: +Or if the constant is zero (i.e. `FooBar` == 0 and `a` + `FooBar` == `a`), then do this: ```asm ; 3 bytes, 3 cycles @@ -989,7 +989,7 @@ And if the constant is zero (i.e. `FooBar` == 0 and `a` + `FooBar` == `a`), then (The example uses `hl`, but `bc` or `de` would also work.) -You can do: +You can do this: ```asm ; 7 bytes, 11 cycles @@ -1010,7 +1010,7 @@ rept 4 endr ``` -But if `a` is definitely small enough, and its value can be changed, then do: +But if `a` is definitely small enough, and its value can be changed, then do one of these: ```asm ; 7 bytes, 10 cycles; sets a = a * 2; requires a < $80 @@ -1049,7 +1049,7 @@ But if `a` is definitely small enough, and its value can be changed, then do: ld h, 0 ``` -Or if the value of `a` can be changed and you want to optimize for speed over size, do: +Or if the value of `a` can be changed and you want to optimize for speed over size, then do one of these: ```asm ; 8 bytes, 8 cycles; sets a = l @@ -1061,8 +1061,6 @@ Or if the value of `a` can be changed and you want to optimize for speed over si ld l, a ``` -Or do: - ```asm ; 8 bytes, 8 cycles; sets a = h swap a @@ -1076,7 +1074,7 @@ Or do: ### Increment or decrement a 16-bit register -When possible, avoid doing: +When possible, avoid doing this: ```asm inc hl ; 1 byte, 2 cycles @@ -1086,7 +1084,7 @@ When possible, avoid doing: dec hl ; 1 byte, 2 cycles ``` -If the low byte *definitely* won't overflow, then do: +If the low byte *definitely* won't overflow, then do this: ```asm inc l ; 1 byte, 1 cycle @@ -1103,7 +1101,7 @@ This is applicable, for instance, if you're reading a data table via `hl` one by (The example uses `hl`, but `bc` or `de` would also work.) -Don't do: +Don't do this: ```asm ; 8 bytes, 8 cycles @@ -1125,7 +1123,7 @@ Don't do: ld h, a ``` -And don't do: +And don't do this: ```asm ; 7 bytes, 7 cycles @@ -1149,7 +1147,7 @@ And don't do: (That would be applying the "[Set `a` to some value plus or minus carry](#set-a-to-some-value-plus-or-minus-carry)" optimization to part of the first way.) -And don't do: +And don't do this: ```asm ; 7 bytes, 7 or 8 cycles @@ -1173,7 +1171,7 @@ And don't do: (That would be applying the "[Add or subtract the carry flag from a register besides `a`](#add-or-subtract-the-carry-flag-from-a-register-besides-a)" optimization to part of the first way.) -But do: +Instead, do this: ```asm ; 3 bytes, 4 or 5 cycles @@ -1192,7 +1190,7 @@ But do: ### Load from an address to `hl` -Don't do: +Don't do this: ```asm ; 8 bytes, 10 cycles @@ -1202,7 +1200,7 @@ Don't do: ld h, a ``` -But do: +Instead, do this: ```asm ; 6 bytes, 8 cycles @@ -1212,7 +1210,7 @@ But do: ld l, a ``` -And don't do: +And don't do this: ```asm ; 8 bytes, 10 cycles @@ -1222,7 +1220,7 @@ And don't do: ld l, a ``` -But do: +Instead, do this: ```asm ; 6 bytes, 8 cycles @@ -1237,7 +1235,7 @@ But do: (The example uses `hl` and `de`, but any pair of `bc`, `de`, or `hl` would also work.) -If you care about speed: +If you care about speed, then do this: ```asm ; 6 bytes, 6 cycles @@ -1249,7 +1247,7 @@ If you care about speed: ld l, a ``` -If you care about size: +If you care about size, then do this: ```asm ; 4 bytes, 9 cycles @@ -1264,10 +1262,10 @@ If you care about size: (The example uses `hl` and `de`, but any pair of `bc`, `de`, or `hl` would also work.) -Don't do: +Don't do this: ```asm - ; 9 bytes, 10 cycles, modifies subtrahend de + ; 9 bytes, 10 cycles; modifies subtrahend de ld a, $ff xor d ld d, a @@ -1277,10 +1275,10 @@ Don't do: add hl, de ``` -And don't do: +And don't do this: ```asm - ; 7 bytes, 8 cycles, modifies subtrahend de + ; 7 bytes, 8 cycles; modifies subtrahend de ld a, d cpl ld d, a @@ -1290,7 +1288,7 @@ And don't do: add hl, de ``` -But do: +Instead, do this: ```asm ; 6 bytes, 6 cycles @@ -1307,7 +1305,7 @@ But do: (The example uses `bc`, but `hl` or `de` would also work.) -Don't do: +Don't do this: ```asm ; 4 bytes, 4 cycles @@ -1315,7 +1313,7 @@ Don't do: ld c, BAR ``` -But do: +Instead, do this: ```asm ld bc, FOO << 8 | BAR ; 3 bytes, 3 cycles @@ -1330,7 +1328,7 @@ Or better, use the `lb` macro in [macros/code.asm](../blob/master/macros/code.as ### Load a constant into `[hl]` -Don't do: +Don't do this: ```asm ; 3 bytes, 4 cycles @@ -1338,7 +1336,7 @@ Don't do: ld [hl], a ``` -But do: +Instead, do this: ```asm ld [hl], FOOBAR ; 2 bytes, 3 cycles @@ -1347,7 +1345,7 @@ But do: ### Increment or decrement `[hl]` -Don't do: +Don't do this: ```asm ; 3 bytes, 5 cycles @@ -1363,7 +1361,7 @@ Don't do: ld [hl], a ``` -But do: +Instead, do this: ```asm inc [hl] ; 1 bytes, 3 cycles @@ -1376,7 +1374,7 @@ But do: ### Load a constant into `[hl]` and increment or decrement `hl` -Don't do: +Don't do this: ```asm ; 2 bytes, 4 cycles @@ -1390,7 +1388,7 @@ Don't do: dec hl ``` -But do: +Instead, do this: ```asm ld [hli], a ; 1 bytes, 2 cycles @@ -1400,7 +1398,7 @@ But do: ld [hld], a ; 1 bytes, 2 cycles ``` -And if you can use `a`, then don't do: +And if you can use `a`, then don't do this: ```asm ; 3 bytes, 5 cycles @@ -1414,7 +1412,7 @@ And if you can use `a`, then don't do: dec hl ``` -But do: +Instead, do this: ```asm ; 3 bytes, 4 cycles @@ -1434,48 +1432,62 @@ But do: ### Relative jumps -Don't do: +Don't do this: ```asm jp Somewhere ; 3 bytes, 4 cycles ``` -But do: +Instead, do this: ```asm jr Somewhere ; 2 bytes, 3 cycles ``` -This only applies if `Somewhere` is within ±127 bytes of the jump. +This only applies if `Somewhere` is within ±128 bytes of the jump. + +You can define a `jmp` macro to use instead of `jp`, which will warn you when it can be `jr` instead: + +``` +jmp: MACRO + if _NARG == 1 + jp \1 + else + jp \1, \2 + shift + endc + assert warn, (\1) - @ > 127 || (\1) - @ < -129, "jp can be jr" +ENDM +``` ### Compare `a` to 0 -Don't do: +Don't do this: ```asm cp 0 ; 2 bytes, 2 cycles ``` -And don't do: +And don't do this: ```asm or 0 ; 2 bytes, 2 cycles ``` -And don't do: +And don't do this: ```asm and $ff ; 2 bytes, 2 cycles ``` -But do: +Instead, do this: ```asm or a ; 1 byte, 1 cycle ``` -Or do: +Or do this: ```asm and a ; 1 byte, 1 cycle @@ -1484,27 +1496,31 @@ Or do: ### Compare `a` to 1 +Do this: + ```asm - cp 1 ; 2 bytes, 2 cycles + cp 1 ; 2 bytes, 2 cycles; updates Z and C flags ``` -If you don't care about carry or the value in `a`: +Or if you don't care about the value in `a`, and don't need to set the carry flag, then do this: ```asm - dec a ; 1 byte, 1 cycle, decrements a + dec a ; 1 byte, 1 cycle; decrements a, updates Z flag ``` -Note that you can still do `inc a` afterwards, which is one cycle faster if the jump is taken. Compare: +Note that you can still do `inc a` afterwards, which is one cycle faster if the jump is taken. Compare this: ```asm + ; 4 bytes, 4 or 5 cycles cp 1 jr z, .equals1 ``` -with: +with this: ```asm + ; 4 bytes, 4 cycles dec a jr z, .equals1 inc a @@ -1515,26 +1531,30 @@ with: (255, or $FF in hexadecimal, is the same as −1 due to [two's complement](https://en.wikipedia.org/wiki/Two%27s_complement).) +Do this: + ```asm - cp $ff ; 2 bytes, 2 cycles + cp $ff ; 2 bytes, 2 cycles; updates Z and C flags ``` -If you don't care about carry or the value in `a`: +Or if you don't care about the value in `a`, and don't need to set the carry flag, then do this: ```asm - inc a ; 1 byte, 1 cycle, increments a + inc a ; 1 byte, 1 cycle; increments a, updates Z flag ``` -Note that you can still do `dec a` afterwards, which is one cycle faster if the jump is taken. Compare: +Note that you can still do `dec a` afterwards, which is one cycle faster if the jump is taken. Compare this: ```asm + ; 4 bytes, 4 or 5 cycles cp $ff jr z, .equals255 ``` -with: +with this: ```asm + ; 4 bytes, 4 cycles inc a jr z, .equals255 dec a @@ -1543,7 +1563,7 @@ with: ### Compare `a` to 0 after masking it -Don't do: +Don't do this: ```asm ; 3 bytes, 3 cycles; sets zero flag if a == 0 @@ -1551,7 +1571,7 @@ Don't do: and a ``` -But do: +Instead, do this: ```asm and MASK ; 2 bytes, 2 cycles; sets zero flag if a == 0 @@ -1560,26 +1580,26 @@ But do: ### Test whether `a` is negative (compare `a` to $80) -If you don't need to preserve the value in `a`, then don't do: +If you don't need to preserve the value in `a`, then don't do this: ```asm - ; 4 bytes, 4/5 cycles + ; 4 bytes, 4 or 5 cycles cp $80 jr nc, .negative ``` -And don't do: +And don't do this: ```asm - ; 4 bytes, 4/5 cycles + ; 4 bytes, 4 or 5 cycles bit 7, a jr nz, .negative ``` -Instead, do: +Instead, do this: ```asm - ; 3 bytes, 3/4 cycles + ; 3 bytes, 3 or 4 cycles; modifies a rlca jr c, .negative ``` @@ -1590,7 +1610,7 @@ Instead, do: ### Tail call optimization -Don't do: +Don't do this: ```asm ; 4 bytes, 10 cycles @@ -1598,7 +1618,7 @@ Don't do: ret ``` -But do: +Instead, do this: ```asm jp Function ; 3 bytes, 4 cycles @@ -1607,7 +1627,7 @@ But do: ### Call `hl` -Don't do: +Don't do this: ```asm ; 5 bytes, 8 cycles @@ -1620,7 +1640,7 @@ Don't do: (some more code) ``` -But do: +Instead, do this: ```asm ; 3 bytes, 6 cycles @@ -1640,7 +1660,7 @@ _hl_:: ### Inlining -Don't do: +Don't do this: ```asm ; 4 additional bytes, 10 additional cycles @@ -1669,7 +1689,7 @@ You shouldn't do this if `Function` used any `ret`urns besides the one at the ve ### Fallthrough -Don't do: +Don't do this: ```asm (some code) @@ -1681,7 +1701,7 @@ Function: ret ``` -And don't do: +And don't do this: ```asm (some code) @@ -1692,7 +1712,7 @@ Function: ret ``` -But do: +Instead, do this: ```asm (some code) @@ -1709,7 +1729,7 @@ Fallthrough is what you get when you combine inlining with tail calls. You can (The example uses `z`, but `nz`, `c`, or `nc` would also work.) -Don't do: +Don't do this: ```asm (some code) @@ -1723,7 +1743,7 @@ Don't do: (bar code) ``` -But do: +Instead, do this: ```asm (some code) @@ -1741,7 +1761,7 @@ But do: (The example uses `z`, but `nz`, `c`, or `nc` would also work.) -Don't do: +Don't do this: ```asm ; 3 bytes, 3 or 6 cycles @@ -1751,7 +1771,7 @@ Don't do: ... ``` -But do: +Instead, do this: ```asm ; 1 byte, 5 or 2 cycles @@ -1764,7 +1784,7 @@ But do: (The example uses `z`, but `nz`, `c`, or `nc` would also work.) -Don't do: +Don't do this: ```asm ; 5 bytes, 3 or 9 cycles @@ -1773,14 +1793,14 @@ Don't do: .skip ``` -But do: +Instead, do this: ```asm ; 3 bytes, 6 or 3 cycles call z, Foo ``` -And don't do: +And don't do this: ```asm ; 5 bytes, 3 or 9 cycles @@ -1789,7 +1809,7 @@ And don't do: .skip ``` -But do: +Instead, do this: ```asm ; 3 bytes, 6 or 3 cycles @@ -1801,7 +1821,7 @@ But do: (The example uses `z`, but `nz`, `c`, or `nc` would also work.) -Don't do: +Don't do this: ```asm ; 5 bytes, 3 or 14 cycles @@ -1813,7 +1833,7 @@ RstVector38: ret ``` -And don't do: +And don't do this: ```asm ; 3 bytes, 3 or 6 cycles @@ -1823,7 +1843,7 @@ And don't do: ... ``` -And don't do: +And don't do this: ```asm ; 3 bytes, 3 or 6 cycles @@ -1831,7 +1851,7 @@ And don't do: ... ``` -But do: +Instead, do this: ```asm ; 2 bytes, 2 or 7 cycles @@ -1844,7 +1864,7 @@ But do: ### Enable interrupts and return -Don't do: +Don't do this: ```asm ; 2 bytes, 5 cycles @@ -1852,7 +1872,7 @@ Don't do: ret ``` -But do: +Instead, do this: ```asm ; 1 byte, 4 cycles @@ -1865,7 +1885,7 @@ But do: ### Chain comparisons -Don't do: +Don't do this: ```asm cp 1 @@ -1877,7 +1897,7 @@ Don't do: ... ``` -But do: +Instead, do this: ```asm dec a @@ -1889,7 +1909,7 @@ But do: ... ``` -Or do: +Or do this: ```asm dec a @@ -1916,7 +1936,7 @@ Or better, do: dec a ld hl, .jumptable rst JumpTable - ... + ret .jumptable: dw .equals1 @@ -1924,3 +1944,19 @@ Or better, do: dw .equals3 ... ``` + +`JumpTable` is an `rst` routine already defined in [home/header.asm](../blob/master/home/header.asm): + +```asm +JumpTable:: + push de + ld e, a + ld d, 0 + add hl, de + add hl, de + ld a, [hli] + ld h, [hl] + ld l, a + pop de + jp hl +``` |