diff options
-rw-r--r-- | Optimizing-assembly-code.md | 74 |
1 files changed, 48 insertions, 26 deletions
diff --git a/Optimizing-assembly-code.md b/Optimizing-assembly-code.md index dd46669..d9b3811 100644 --- a/Optimizing-assembly-code.md +++ b/Optimizing-assembly-code.md @@ -99,7 +99,7 @@ Don't do: ```asm ; 4 bytes, 4 cycles ld b, a - ld a, CONST + ld a, FOOBAR sub b ``` @@ -108,21 +108,23 @@ But do: ```asm ; 3 bytes, 3 cycles cpl - add CONST + 1 + add FOOBAR + 1 ``` +("What's [foobar](https://en.wikipedia.org/wiki/Foobar)?") + ### 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`).) +(The example sets `a` to `FOO` if the carry flag is set (`c`), or `BAR` is the carry flag is not set (`nc`).) Don't do: ```asm ; 6 bytes, 6 or 7 cycles - ld a, ONE + ld a, FOO jr c, .carry - ld a, TWO + ld a, BAR .carry ``` @@ -130,9 +132,9 @@ And don't do: ```asm ; 6 bytes, 6 or 7 cycles - ld a, TWO + ld a, BAR jr nc, .no_carry - ld a, ONE + ld a, FOO .no_carry ``` @@ -141,8 +143,8 @@ But do: ```asm ; 5 bytes, 5 cycles sbc a ; if carry, then $ff, else 0 - and ONE - TWO ; $ff becomes ONE - TWO, 0 stays 0 - add TWO ; ONE - TWO becomes ONE, 0 becomes TWO + and FOO - BAR ; $ff becomes FOO - BAR, 0 stays 0 + add BAR ; FOO - BAR becomes FOO, 0 becomes BAR ``` Or do: @@ -150,25 +152,41 @@ Or do: ```asm ; 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 + and FOO ^ BAR ; $ff becomes FOO ^ BAR, 0 stays 0 + xor BAR ; FOO ^ BAR becomes FOO, 0 becomes BAR ``` -If `ONE` is 0 (i.e. set `a` to 0 if carry), then do: +If `FOO` is 0 (i.e. set `a` to 0 if carry), then do: ```asm ; 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 BAR ; 0 stays 0, $ff becomes BAR ``` -If `TWO` is 0 (i.e. set `a` to 0 if not carry), then do: +If `BAR` is 0 (i.e. set `a` to 0 if not carry), then do: ```asm ; 3 bytes, 3 cycles sbc a ; if carry, then $ff, else 0 - and ONE ; $ff becomes ONE, 0 stays 0 + and FOO ; $ff becomes FOO, 0 stays 0 +``` + +If `FOO` equals `BAR - 1`, then do: + +```asm + ; 3 bytes, 3 cycles + sbc a ; if carry, then $ff aka -1, else 0 + add BAR ; -1 becomes BAR - 1 aka FOO, 0 becomes BAR +``` + +If `FOO` equals `BAR - 2`, then do: + +```asm + ; 3 bytes, 3 cycles + sbc a ; if carry, then $ff aka -1, else 0; doesn't change the carry flag + sbc -BAR ; -1 becomes BAR - 2 aka FOO, 0 becomes BAR ``` @@ -357,20 +375,20 @@ Don't do: ```asm ; 4 bytes, 4 cycles - ld b, ONE - ld c, TWO + ld b, FOO + ld c, BAR ``` But do: ```asm - ld bc, ONE << 8 | TWO ; 3 bytes, 3 cycles + ld bc, FOO << 8 | BAR ; 3 bytes, 3 cycles ``` Or better, use the `lb` macro in [macros/code.asm](../blob/master/macros/code.asm): ```asm - lb bc, ONE, TWO ; 3 bytes, 3 cycles + lb bc, FOO, BAR ; 3 bytes, 3 cycles ``` @@ -380,14 +398,14 @@ Don't do: ```asm ; 3 bytes, 4 cycles - ld a, CONST + ld a, FOOBAR ld [hl], a ``` But do: ```asm - ld [hl], CONST ; 2 bytes, 3 cycles + ld [hl], FOOBAR ; 2 bytes, 3 cycles ``` @@ -571,22 +589,26 @@ But do: ```asm ; 5 bytes, 8 cycles + (some code) ld de, .return push de jp hl -.return - ... +.return: + (some more code) ``` But do: ```asm - call _hl_ ; 4 bytes, 7 cycles, counting the definition of _hl_ - ... + ; 3 bytes, 6 cycles + ; (4 bytes, 7 cycles, counting the definition of _hl_) + (some code) + call _hl_ + (some more code) ``` -`_hl_` is a routine already defined in [home.asm](../blob/master/home.asm): +`_hl_` is a routine already defined in [home/call_regs.asm](../blob/master/home/call_regs.asm): ```asm _hl_:: |