From 6e1eeeebfb453fa7c871869c19375ce60fbd7413 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sat, 27 Jul 2019 16:01:55 -0700 Subject: 5485 - promote SubX to top-level --- html/subx/examples/ex11.subx.html | 423 -------------------------------------- 1 file changed, 423 deletions(-) delete mode 100644 html/subx/examples/ex11.subx.html (limited to 'html/subx/examples/ex11.subx.html') diff --git a/html/subx/examples/ex11.subx.html b/html/subx/examples/ex11.subx.html deleted file mode 100644 index c8ad42c9..00000000 --- a/html/subx/examples/ex11.subx.html +++ /dev/null @@ -1,423 +0,0 @@ - - - - -Mu - subx/examples/ex11.subx - - - - - - - - - - -https://github.com/akkartik/mu/blob/master/subx/examples/ex11.subx -
-  1 # Null-terminated vs length-prefixed ascii strings.
-  2 #
-  3 # By default we create strings with a 4-byte length prefix rather than a null suffix.
-  4 # However we still need null-prefixed strings when interacting with the Linux
-  5 # kernel in a few places. This layer implements a function for comparing
-  6 # a null-terminated 'kernel string' with a length-prefixed 'SubX string'.
-  7 #
-  8 # To run (from the subx directory):
-  9 #   $ ./subx translate examples/ex11.subx -o examples/ex11
- 10 #   $ ./subx run examples/ex11  # runs a series of tests
- 11 #   ......  # all tests pass
- 12 #
- 13 # (We can't yet run the tests when given a "test" commandline argument,
- 14 # because checking for it would require the function being tested! Breakage
- 15 # would cause tests to not run, rather than to fail as we'd like.)
- 16 
- 17 == code 0x09000000
- 18 #   instruction                     effective address                                                   register    displacement    immediate
- 19 # . op          subop               mod             rm32          base        index         scale       r32
- 20 # . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes
- 21 
- 22 Entry:  # run all tests
- 23     e8/call  run-tests/disp32  # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
- 24     # syscall(exit, EAX)
- 25     89/copy                         3/mod/direct    3/rm32/EBX    .           .             .           0/r32/EAX   .               .                 # copy EAX to EBX
- 26     b8/copy-to-EAX  1/imm32/exit
- 27     cd/syscall  0x80/imm8
- 28 
- 29 # compare a null-terminated ascii string with a more idiomatic length-prefixed byte array
- 30 # reason for the name: the only place we should have null-terminated ascii strings is from commandline args
- 31 kernel-string-equal?:  # s : null-terminated ascii string, benchmark : length-prefixed ascii string -> EAX : boolean
- 32     # pseudocode:
- 33     #   n = benchmark->length
- 34     #   s1 = s
- 35     #   s2 = benchmark->data
- 36     #   i = 0
- 37     #   while i < n
- 38     #     c1 = *s1
- 39     #     c2 = *s2
- 40     #     if (c1 == 0) return false
- 41     #     if (c1 != c2) return false
- 42     #     ++s1, ++s2, ++i
- 43     #   return *s1 == 0
- 44     #
- 45     # registers:
- 46     #   i: ECX
- 47     #   n: EDX
- 48     #   s1: EDI
- 49     #   s2: ESI
- 50     #   c1: EAX
- 51     #   c2: EBX
- 52     #
- 53     # . prolog
- 54     55/push-EBP
- 55     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
- 56     # . save registers
- 57     51/push-ECX
- 58     52/push-EDX
- 59     53/push-EBX
- 60     56/push-ESI
- 61     57/push-EDI
- 62     # s1/EDI = s
- 63     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           7/r32/EDI   8/disp8         .                 # copy *(EBP+8) to EDI
- 64     # n/EDX = benchmark->length
- 65     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           2/r32/EDX   0xc/disp8       .                 # copy *(EBP+12) to EDX
- 66     8b/copy                         0/mod/indirect  2/rm32/EDX    .           .             .           2/r32/EDX   .               .                 # copy *EDX to EDX
- 67     # s2/ESI = benchmark->data
- 68     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           6/r32/ESI   0xc/disp8       .                 # copy *(EBP+12) to ESI
- 69     81          0/subop/add         3/mod/direct    6/rm32/ESI    .           .             .           .           .               4/imm32           # add to ESI
- 70     # i/ECX = c1/EAX = c2/EBX = 0
- 71     b9/copy-to-ECX  0/imm32/exit
- 72     b8/copy-to-EAX  0/imm32
- 73     bb/copy-to-EBX  0/imm32
- 74 $kernel-string-equal?:loop:
- 75     # if (i >= n) break
- 76     39/compare                      3/mod/direct    1/rm32/ECX    .           .             .           2/r32/EDX   .               .                 # compare ECX with EDX
- 77     7d/jump-if-greater-or-equal  $kernel-string-equal?:break/disp8
- 78     # c1 = *s1
- 79     8a/copy-byte                    0/mod/indirect  7/rm32/EDI    .           .             .           0/r32/AL    .               .                 # copy byte at *EDI to AL
- 80     # c2 = *s2
- 81     8a/copy-byte                    0/mod/indirect  6/rm32/ESI    .           .             .           3/r32/BL    .               .                 # copy byte at *ESI to BL
- 82     # if (c1 == 0) return false
- 83     3d/compare-EAX-and  0/imm32
- 84     74/jump-if-equal  $kernel-string-equal?:false/disp8
- 85     # if (c1 != c2) return false
- 86     39/compare                      3/mod/direct    0/rm32/EAX    .           .             .           3/r32/EBX   .               .                 # compare EAX and EBX
- 87     75/jump-if-not-equal  $kernel-string-equal?:false/disp8
- 88     # ++i
- 89     41/increment-ECX
- 90     # ++s1
- 91     47/increment-EDI
- 92     # ++s2
- 93     46/increment-ESI
- 94     eb/jump  $kernel-string-equal?:loop/disp8
- 95 $kernel-string-equal?:break:
- 96     # return *s1 == 0
- 97     8a/copy-byte                    0/mod/indirect  7/rm32/EDI    .           .             .           0/r32/AL    .               .                 # copy byte at *EDI to AL
- 98     3d/compare-EAX-and  0/imm32
- 99     75/jump-if-not-equal  $kernel-string-equal?:false/disp8
-100 $kernel-string-equal?:true:
-101     b8/copy-to-EAX  1/imm32
-102     eb/jump  $kernel-string-equal?:end/disp8
-103 $kernel-string-equal?:false:
-104     b8/copy-to-EAX  0/imm32
-105 $kernel-string-equal?:end:
-106     # . restore registers
-107     5f/pop-to-EDI
-108     5e/pop-to-ESI
-109     5b/pop-to-EBX
-110     5a/pop-to-EDX
-111     59/pop-to-ECX
-112     # . epilog
-113     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
-114     5d/pop-to-EBP
-115     c3/return
-116 
-117 # - tests
-118 
-119 test-compare-null-kernel-string-with-empty-array:
-120     # EAX = kernel-string-equal?(Null-kernel-string, "")
-121     # . . push args
-122     68/push  ""/imm32
-123     68/push  Null-kernel-string/imm32
-124     # . . call
-125     e8/call  kernel-string-equal?/disp32
-126     # . . discard args
-127     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-128     # check-ints-equal(EAX, 1, msg)
-129     # . . push args
-130     68/push  "F - test-compare-null-kernel-string-with-empty-array"/imm32
-131     68/push  1/imm32/true
-132     50/push-EAX
-133     # . . call
-134     e8/call  check-ints-equal/disp32
-135     # . . discard args
-136     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-137     c3/return
-138 
-139 test-compare-null-kernel-string-with-non-empty-array:
-140     # EAX = kernel-string-equal?(Null-kernel-string, "Abc")
-141     # . . push args
-142     68/push  "Abc"/imm32
-143     68/push  Null-kernel-string/imm32
-144     # . . call
-145     e8/call  kernel-string-equal?/disp32
-146     # . . discard args
-147     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-148     # check-ints-equal(EAX, 0, msg)
-149     # . . push args
-150     68/push  "F - test-compare-null-kernel-string-with-non-empty-array"/imm32
-151     68/push  0/imm32/false
-152     50/push-EAX
-153     # . . call
-154     e8/call  check-ints-equal/disp32
-155     # . . discard args
-156     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-157     c3/return
-158 
-159 test-compare-kernel-string-with-equal-array:
-160     # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Abc")
-161     # . . push args
-162     68/push  "Abc"/imm32
-163     68/push  _test-Abc-kernel-string/imm32
-164     # . . call
-165     e8/call  kernel-string-equal?/disp32
-166     # . . discard args
-167     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-168     # check-ints-equal(EAX, 1, msg)
-169     # . . push args
-170     68/push  "F - test-compare-kernel-string-with-equal-array"/imm32
-171     68/push  1/imm32/true
-172     50/push-EAX
-173     # . . call
-174     e8/call  check-ints-equal/disp32
-175     # . . discard args
-176     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-177     c3/return
-178 
-179 test-compare-kernel-string-with-inequal-array:
-180     # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Adc")
-181     # . . push args
-182     68/push  "Adc"/imm32
-183     68/push  _test-Abc-kernel-string/imm32
-184     # . . call
-185     e8/call  kernel-string-equal?/disp32
-186     # . . discard args
-187     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-188     # check-ints-equal(EAX, 0, msg)
-189     # . . push args
-190     68/push  "F - test-compare-kernel-string-with-equal-array"/imm32
-191     68/push  0/imm32/false
-192     50/push-EAX
-193     # . . call
-194     e8/call  check-ints-equal/disp32
-195     # . . discard args
-196     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-197     c3/return
-198 
-199 test-compare-kernel-string-with-empty-array:
-200     # EAX = kernel-string-equal?(_test-Abc-kernel-string, "")
-201     # . . push args
-202     68/push  ""/imm32
-203     68/push  _test-Abc-kernel-string/imm32
-204     # . . call
-205     e8/call  kernel-string-equal?/disp32
-206     # . . discard args
-207     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-208     # check-ints-equal(EAX, 0, msg)
-209     # . . push args
-210     68/push  "F - test-compare-kernel-string-with-equal-array"/imm32
-211     68/push  0/imm32/false
-212     50/push-EAX
-213     # . . call
-214     e8/call  check-ints-equal/disp32
-215     # . . discard args
-216     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-217     c3/return
-218 
-219 test-compare-kernel-string-with-shorter-array:
-220     # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Ab")
-221     # . . push args
-222     68/push  "Ab"/imm32
-223     68/push  _test-Abc-kernel-string/imm32
-224     # . . call
-225     e8/call  kernel-string-equal?/disp32
-226     # . . discard args
-227     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-228     # check-ints-equal(EAX, 0, msg)
-229     # . . push args
-230     68/push  "F - test-compare-kernel-string-with-shorter-array"/imm32
-231     68/push  0/imm32/false
-232     50/push-EAX
-233     # . . call
-234     e8/call  check-ints-equal/disp32
-235     # . . discard args
-236     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-237     c3/return
-238 
-239 test-compare-kernel-string-with-longer-array:
-240     # EAX = kernel-string-equal?(_test-Abc-kernel-string, "Abcd")
-241     # . . push args
-242     68/push  "Abcd"/imm32
-243     68/push  _test-Abc-kernel-string/imm32
-244     # . . call
-245     e8/call  kernel-string-equal?/disp32
-246     # . . discard args
-247     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-248     # check-ints-equal(EAX, 0, msg)
-249     # . . push args
-250     68/push  "F - test-compare-kernel-string-with-longer-array"/imm32
-251     68/push  0/imm32/false
-252     50/push-EAX
-253     # . . call
-254     e8/call  check-ints-equal/disp32
-255     # . . discard args
-256     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-257     c3/return
-258 
-259 # - helpers
-260 
-261 # print msg to stderr if a != b, otherwise print "."
-262 check-ints-equal:  # (a : int, b : int, msg : (address array byte)) -> boolean
-263     # . prolog
-264     55/push-EBP
-265     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-266     # . save registers
-267     51/push-ECX
-268     53/push-EBX
-269     # load args into EAX, EBX and ECX
-270     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           0/r32/EAX   8/disp8         .                 # copy *(EBP+8) to EAX
-271     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           3/r32/EBX   0xc/disp8       .                 # copy *(EBP+12) to EBX
-272     # if (EAX == b/EBX) print('.') and return
-273     39/compare                      3/mod/direct    0/rm32/EAX    .           .             .           3/r32/EBX   .               .                 # compare EAX and EBX
-274     75/jump-if-unequal  $check-ints-equal:else/disp8
-275     # . write-stderr('.')
-276     # . . push args
-277     68/push  "."/imm32
-278     # . . call
-279     e8/call  write-stderr/disp32
-280     # . . discard args
-281     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-282     # . return
-283     eb/jump  $check-ints-equal:end/disp8
-284     # otherwise print(msg)
-285 $check-ints-equal:else:
-286     # copy msg into ECX
-287     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           1/r32/ECX   0x10/disp8       .                # copy *(EBP+16) to ECX
-288     # print(ECX)
-289     # . . push args
-290     51/push-ECX
-291     # . . call
-292     e8/call  write-stderr/disp32
-293     # . . discard args
-294     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-295     # print newline
-296     # . . push args
-297     68/push  Newline/imm32
-298     # . . call
-299     e8/call  write-stderr/disp32
-300     # . . discard args
-301     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-302 $check-ints-equal:end:
-303     # . restore registers
-304     5b/pop-to-EBX
-305     59/pop-to-ECX
-306     # end
-307     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
-308     5d/pop-to-EBP
-309     c3/return
-310 
-311 write-stderr:  # s : (address array byte) -> <void>
-312     # . prolog
-313     55/push-EBP
-314     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-315     # . save registers
-316     50/push-EAX
-317     51/push-ECX
-318     52/push-EDX
-319     53/push-EBX
-320     # syscall(write, 2/stderr, (data) s+4, (size) *s)
-321     # . . fd = 2 (stderr)
-322     bb/copy-to-EBX  2/imm32
-323     # . . x = s+4
-324     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           1/r32/ECX   8/disp8         .                 # copy *(EBP+8) to ECX
-325     81          0/subop/add         3/mod/direct    1/rm32/ECX    .           .             .           .           .               4/imm32           # add to ECX
-326     # . . size = *s
-327     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           2/r32/EDX   8/disp8         .                 # copy *(EBP+8) to EDX
-328     8b/copy                         0/mod/indirect  2/rm32/EDX    .           .             .           2/r32/EDX   .               .                 # copy *EDX to EDX
-329     # . . syscall
-330     b8/copy-to-EAX  4/imm32/write
-331     cd/syscall  0x80/imm8
-332     # . restore registers
-333     5b/pop-to-EBX
-334     5a/pop-to-EDX
-335     59/pop-to-ECX
-336     58/pop-to-EAX
-337     # . end
-338     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
-339     5d/pop-to-EBP
-340     c3/return
-341 
-342 == data 0x0a000000
-343 
-344 Newline:
-345     # size
-346     1/imm32
-347     # data
-348     0a/newline
-349 
-350 # for kernel-string-equal tests
-351 Null-kernel-string:
-352     00/null
-353 
-354 _test-Abc-kernel-string:
-355     41/A 62/b 63/c 00/null
-356 
-357 # . . vim:nowrap:textwidth=0
-
- - - -- cgit 1.4.1-2-gfad0