about summary refs log tree commit diff stats
path: root/subx/examples/ex11.subx
diff options
context:
space:
mode:
Diffstat (limited to 'subx/examples/ex11.subx')
-rw-r--r--subx/examples/ex11.subx135
1 files changed, 71 insertions, 64 deletions
diff --git a/subx/examples/ex11.subx b/subx/examples/ex11.subx
index 7fb83eb6..49e0c753 100644
--- a/subx/examples/ex11.subx
+++ b/subx/examples/ex11.subx
@@ -28,7 +28,28 @@
 
 # compare a null-terminated ascii string with a more idiomatic length-prefixed byte array
 # reason for the name: the only place we should have null-terminated ascii strings is from commandline args
-kernel-string-equal:  # s : null-terminated ascii string, benchmark : length-prefixed ascii string -> EAX : boolean
+kernel-string-equal?:  # s : null-terminated ascii string, benchmark : length-prefixed ascii string -> EAX : boolean
+    # pseudocode:
+    #   n = benchmark->length
+    #   s1 = s
+    #   s2 = benchmark->data
+    #   i = 0
+    #   while (i < n)
+    #     c1 = *s1
+    #     c2 = *s2
+    #     if (c1 == 0) return false
+    #     if (c1 != c2) return false
+    #     ++s1, ++s2, ++i
+    #   return *s1 == 0
+    #
+    # registers:
+    #   i: ECX
+    #   n: EDX
+    #   s1: EDI
+    #   s2: ESI
+    #   c1: EAX
+    #   c2: EBX
+    #
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
@@ -38,72 +59,57 @@ kernel-string-equal:  # s : null-terminated ascii string, benchmark : length-pre
     53/push-EBX
     56/push-ESI
     57/push-EDI
-
-    # pseudocode:
-    #   initialize n = b->length
-    #   initialize s1 = s
-    #   initialize s2 = b->data
-    #   i = 0
-    #   for (i = 0; i < n; ++n)
-    #     c1 = *s1
-    #     c2 = *s2
-    #     if c1 == 0
-    #       return false
-    #     if c1 != c2
-    #       return false
-    #   return *s1 == 0
-    # initialize s into EDI
+    # s1/EDI = s
     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           7/r32/EDI   8/disp8         .                 # copy *(EBP+8) to EDI
-    # initialize benchmark length n into EDX
+    # n/EDX = benchmark->length
     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           2/r32/EDX   0xc/disp8       .                 # copy *(EBP+12) to EDX
     8b/copy                         0/mod/indirect  2/rm32/EDX    .           .             .           2/r32/EDX   .               .                 # copy *EDX to EDX
-    # initialize benchmark data into ESI
+    # s2/ESI = benchmark->data
     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           6/r32/ESI   0xc/disp8       .                 # copy *(EBP+12) to ESI
     81          0/subop/add         3/mod/direct    6/rm32/ESI    .           .             .           .           .               4/imm32           # add to ESI
-    # initialize loop counter i into ECX
+    # i/ECX = c1/EAX = c2/EBX = 0
     b9/copy-to-ECX  0/imm32/exit
-    # while (i/ECX < n/EDX)
-$kernel-string-equal:loop:
-    39/compare                      3/mod/direct    1/rm32/ECX    .           .             .           2/r32/EDX   .               .                 # compare ECX with EDX
-    74/jump-if-equal  $kernel-string-equal:break/disp8
-    # c1/EAX, c2/EBX = *s, *benchmark
     b8/copy-to-EAX  0/imm32
-    8a/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           0/r32/EAX   .               .                 # copy byte at *EDI to lower byte of EAX
     bb/copy-to-EBX  0/imm32
+$kernel-string-equal?:loop:
+    # if (i >= n) break
+    39/compare                      3/mod/direct    1/rm32/ECX    .           .             .           2/r32/EDX   .               .                 # compare ECX with EDX
+    7d/jump-if-greater-or-equal  $kernel-string-equal?:break/disp8
+    # c1 = *s1
+    8a/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           0/r32/EAX   .               .                 # copy byte at *EDI to lower byte of EAX
+    # c2 = *s2
     8a/copy                         0/mod/indirect  6/rm32/ESI    .           .             .           3/r32/EBX   .               .                 # copy byte at *ESI to lower byte of EBX
     # if (c1 == 0) return false
     3d/compare-EAX  0/imm32
-    74/jump-if-equal  $kernel-string-equal:false/disp8
+    74/jump-if-equal  $kernel-string-equal?:false/disp8
     # if (c1 != c2) return false
     39/compare                      3/mod/direct    0/rm32/EAX    .           .             .           3/r32/EBX   .               .                 # compare EAX with EBX
-    75/jump-if-not-equal  $kernel-string-equal:false/disp8
-    # ++s1, ++s2, ++i
+    75/jump-if-not-equal  $kernel-string-equal?:false/disp8
+    # ++i
     41/inc-ECX
-    46/inc-ESI
+    # ++s1
     47/inc-EDI
-    # end while
-    eb/jump  $kernel-string-equal:loop/disp8
-$kernel-string-equal:break:
-    # if (*s/EDI == 0) return true
-    b8/copy-to-EAX  0/imm32
+    # ++s2
+    46/inc-ESI
+    eb/jump  $kernel-string-equal?:loop/disp8
+$kernel-string-equal?:break:
+    # return *s1 == 0
     8a/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           0/r32/EAX   .               .                 # copy byte at *EDI to lower byte of EAX
-    81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # compare EAX
-    75/jump-if-not-equal  $kernel-string-equal:false/disp8
+    3d/compare-EAX  0/imm32
+    75/jump-if-not-equal  $kernel-string-equal?:false/disp8
+$kernel-string-equal?:true:
     b8/copy-to-EAX  1/imm32
-$kernel-string-equal:true:
-    eb/jump  $kernel-string-equal:end/disp8
-    # return false
-$kernel-string-equal:false:
+    eb/jump  $kernel-string-equal?:end/disp8
+$kernel-string-equal?:false:
     b8/copy-to-EAX  0/imm32
-
-$kernel-string-equal:end:
+$kernel-string-equal?:end:
     # . restore registers
     5f/pop-to-EDI
     5e/pop-to-ESI
     5b/pop-to-EBX
     5a/pop-to-EDX
     59/pop-to-ECX
-    # end
+    # . epilog
     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
     5d/pop-to-EBP
     c3/return
@@ -111,12 +117,12 @@ $kernel-string-equal:end:
 # - tests
 
 test-compare-null-kernel-string-with-empty-array:
-    # EAX = kernel-string-equal(Null-kernel-string, "")
+    # EAX = kernel-string-equal?(Null-kernel-string, "")
     # . . push args
     68/push  ""/imm32
     68/push  Null-kernel-string/imm32
     # . . call
-    e8/call  kernel-string-equal/disp32
+    e8/call  kernel-string-equal?/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
     # check-ints-equal(EAX, 1, msg)
@@ -131,12 +137,12 @@ test-compare-null-kernel-string-with-empty-array:
     c3/return
 
 test-compare-null-kernel-string-with-non-empty-array:
-    # EAX = kernel-string-equal(Null-kernel-string, "Abc")
+    # EAX = kernel-string-equal?(Null-kernel-string, "Abc")
     # . . push args
     68/push  "Abc"/imm32
     68/push  Null-kernel-string/imm32
     # . . call
-    e8/call  kernel-string-equal/disp32
+    e8/call  kernel-string-equal?/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
     # check-ints-equal(EAX, 0, msg)
@@ -151,12 +157,12 @@ test-compare-null-kernel-string-with-non-empty-array:
     c3/return
 
 test-compare-kernel-string-with-equal-array:
-    # EAX = kernel-string-equal(Abc-kernel-string, "Abc")
+    # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Abc")
     # . . push args
     68/push  "Abc"/imm32
-    68/push  Abc-kernel-string/imm32
+    68/push  _test-Abc-kernel-string/imm32
     # . . call
-    e8/call  kernel-string-equal/disp32
+    e8/call  kernel-string-equal?/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
     # check-ints-equal(EAX, 1, msg)
@@ -171,12 +177,12 @@ test-compare-kernel-string-with-equal-array:
     c3/return
 
 test-compare-kernel-string-with-inequal-array:
-    # EAX = kernel-string-equal(Abc-kernel-string, "Adc")
+    # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Adc")
     # . . push args
     68/push  "Adc"/imm32
-    68/push  Abc-kernel-string/imm32
+    68/push  _test-Abc-kernel-string/imm32
     # . . call
-    e8/call  kernel-string-equal/disp32
+    e8/call  kernel-string-equal?/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
     # check-ints-equal(EAX, 0, msg)
@@ -191,12 +197,12 @@ test-compare-kernel-string-with-inequal-array:
     c3/return
 
 test-compare-kernel-string-with-empty-array:
-    # EAX = kernel-string-equal(Abc-kernel-string, "")
+    # EAX = kernel-string-equal?(_test-Abc-kernel-string, "")
     # . . push args
     68/push  ""/imm32
-    68/push  Abc-kernel-string/imm32
+    68/push  _test-Abc-kernel-string/imm32
     # . . call
-    e8/call  kernel-string-equal/disp32
+    e8/call  kernel-string-equal?/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
     # check-ints-equal(EAX, 0, msg)
@@ -211,12 +217,12 @@ test-compare-kernel-string-with-empty-array:
     c3/return
 
 test-compare-kernel-string-with-shorter-array:
-    # EAX = kernel-string-equal(Abc-kernel-string, "Ab")
+    # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Ab")
     # . . push args
     68/push  "Ab"/imm32
-    68/push  Abc-kernel-string/imm32
+    68/push  _test-Abc-kernel-string/imm32
     # . . call
-    e8/call  kernel-string-equal/disp32
+    e8/call  kernel-string-equal?/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
     # check-ints-equal(EAX, 0, msg)
@@ -231,12 +237,12 @@ test-compare-kernel-string-with-shorter-array:
     c3/return
 
 test-compare-kernel-string-with-longer-array:
-    # EAX = kernel-string-equal(Abc-kernel-string, "Abcd")
+    # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Abcd")
     # . . push args
     68/push  "Abcd"/imm32
-    68/push  Abc-kernel-string/imm32
+    68/push  _test-Abc-kernel-string/imm32
     # . . call
-    e8/call  kernel-string-equal/disp32
+    e8/call  kernel-string-equal?/disp32
     # . . discard args
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
     # check-ints-equal(EAX, 0, msg)
@@ -263,7 +269,7 @@ check-ints-equal:  # (a : int, b : int, msg : (address array byte)) -> boolean
     # load args into EAX, EBX and ECX
     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           0/r32/EAX   8/disp8         .                 # copy *(EBP+8) to EAX
     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           3/r32/EBX   0xc/disp8       .                 # copy *(EBP+12) to EBX
-    # if EAX == b/EBX print('.') and return
+    # if (EAX == b/EBX) print('.') and return
     39/compare                      3/mod/direct    0/rm32/EAX    .           .             .           3/r32/EBX   .               .                 # compare EAX and EBX
     75/jump-if-unequal  $check-ints-equal:else/disp8
     # . write-stderr('.')
@@ -344,7 +350,8 @@ Newline:
 # for kernel-string-equal tests
 Null-kernel-string:
     00/null
-Abc-kernel-string:
+
+_test-Abc-kernel-string:
     41/A 62/b 63/c 00/null
 
 # . . vim:nowrap:textwidth=0