summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRangi <remy.oukaour+rangi42@gmail.com>2020-03-12 18:50:53 -0400
committerRangi <remy.oukaour+rangi42@gmail.com>2020-03-12 18:50:53 -0400
commit89c6678c9b07de0d5d7316b2aa11dee0c00d4edc (patch)
treee039a5659319f31cf028a8a92c0d9ac687754965
parentcbb501cf629d9b79bdc0edc1500dabd630286623 (diff)
More
-rw-r--r--Optimizing-assembly-code.md74
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_::