From 113bae7311b63e55e55160970718d19bfeeb56c3 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 1 Jan 2020 17:23:29 -0800 Subject: 5856 --- html/examples/ex11.subx.html | 421 ------------------------------------------- 1 file changed, 421 deletions(-) delete mode 100644 html/examples/ex11.subx.html (limited to 'html/examples/ex11.subx.html') diff --git a/html/examples/ex11.subx.html b/html/examples/ex11.subx.html deleted file mode 100644 index 47c0b289..00000000 --- a/html/examples/ex11.subx.html +++ /dev/null @@ -1,421 +0,0 @@ - - - - -Mu - examples/ex11.subx - - - - - - - - - - -https://github.com/akkartik/mu/blob/master/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:
-  9 #   $ ./subx translate init.linux 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
- 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     # exit(eax)
- 25     89/copy                         3/mod/direct    3/rm32/ebx    .           .             .           0/r32/eax   .               .                 # copy eax to ebx
- 26     e8/call  syscall_exit/disp32
- 27 
- 28 # compare a null-terminated ascii string with a more idiomatic length-prefixed byte array
- 29 # reason for the name: the only place we should have null-terminated ascii strings is from commandline args
- 30 kernel-string-equal?:  # s : null-terminated ascii string, benchmark : length-prefixed ascii string -> eax : boolean
- 31     # pseudocode:
- 32     #   n = benchmark->length
- 33     #   s1 = s
- 34     #   s2 = benchmark->data
- 35     #   i = 0
- 36     #   while i < n
- 37     #     c1 = *s1
- 38     #     c2 = *s2
- 39     #     if (c1 == 0) return false
- 40     #     if (c1 != c2) return false
- 41     #     ++s1, ++s2, ++i
- 42     #   return *s1 == 0
- 43     #
- 44     # registers:
- 45     #   i: ecx
- 46     #   n: edx
- 47     #   s1: edi
- 48     #   s2: esi
- 49     #   c1: eax
- 50     #   c2: ebx
- 51     #
- 52     # . prologue
- 53     55/push-ebp
- 54     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
- 55     # . save registers
- 56     51/push-ecx
- 57     52/push-edx
- 58     53/push-ebx
- 59     56/push-esi
- 60     57/push-edi
- 61     # s1/edi = s
- 62     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   8/disp8         .                 # copy *(ebp+8) to edi
- 63     # n/edx = benchmark->length
- 64     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           2/r32/edx   0xc/disp8       .                 # copy *(ebp+12) to edx
- 65     8b/copy                         0/mod/indirect  2/rm32/edx    .           .             .           2/r32/edx   .               .                 # copy *edx to edx
- 66     # s2/esi = benchmark->data
- 67     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   0xc/disp8       .                 # copy *(ebp+12) to esi
- 68     81          0/subop/add         3/mod/direct    6/rm32/esi    .           .             .           .           .               4/imm32           # add to esi
- 69     # i/ecx = c1/eax = c2/ebx = 0
- 70     b9/copy-to-ecx  0/imm32/exit
- 71     b8/copy-to-eax  0/imm32
- 72     bb/copy-to-ebx  0/imm32
- 73 $kernel-string-equal?:loop:
- 74     # if (i >= n) break
- 75     39/compare                      3/mod/direct    1/rm32/ecx    .           .             .           2/r32/edx   .               .                 # compare ecx with edx
- 76     7d/jump-if-greater-or-equal  $kernel-string-equal?:break/disp8
- 77     # c1 = *s1
- 78     8a/copy-byte                    0/mod/indirect  7/rm32/edi    .           .             .           0/r32/AL    .               .                 # copy byte at *edi to AL
- 79     # c2 = *s2
- 80     8a/copy-byte                    0/mod/indirect  6/rm32/esi    .           .             .           3/r32/BL    .               .                 # copy byte at *esi to BL
- 81     # if (c1 == 0) return false
- 82     3d/compare-eax-and  0/imm32
- 83     74/jump-if-equal  $kernel-string-equal?:false/disp8
- 84     # if (c1 != c2) return false
- 85     39/compare                      3/mod/direct    0/rm32/eax    .           .             .           3/r32/ebx   .               .                 # compare eax and ebx
- 86     75/jump-if-not-equal  $kernel-string-equal?:false/disp8
- 87     # ++i
- 88     41/increment-ecx
- 89     # ++s1
- 90     47/increment-edi
- 91     # ++s2
- 92     46/increment-esi
- 93     eb/jump  $kernel-string-equal?:loop/disp8
- 94 $kernel-string-equal?:break:
- 95     # return *s1 == 0
- 96     8a/copy-byte                    0/mod/indirect  7/rm32/edi    .           .             .           0/r32/AL    .               .                 # copy byte at *edi to AL
- 97     3d/compare-eax-and  0/imm32
- 98     75/jump-if-not-equal  $kernel-string-equal?:false/disp8
- 99 $kernel-string-equal?:true:
-100     b8/copy-to-eax  1/imm32
-101     eb/jump  $kernel-string-equal?:end/disp8
-102 $kernel-string-equal?:false:
-103     b8/copy-to-eax  0/imm32
-104 $kernel-string-equal?:end:
-105     # . restore registers
-106     5f/pop-to-edi
-107     5e/pop-to-esi
-108     5b/pop-to-ebx
-109     5a/pop-to-edx
-110     59/pop-to-ecx
-111     # . epilogue
-112     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-113     5d/pop-to-ebp
-114     c3/return
-115 
-116 # - tests
-117 
-118 test-compare-null-kernel-string-with-empty-array:
-119     # eax = kernel-string-equal?(Null-kernel-string, "")
-120     # . . push args
-121     68/push  ""/imm32
-122     68/push  Null-kernel-string/imm32
-123     # . . call
-124     e8/call  kernel-string-equal?/disp32
-125     # . . discard args
-126     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-127     # check-ints-equal(eax, 1, msg)
-128     # . . push args
-129     68/push  "F - test-compare-null-kernel-string-with-empty-array"/imm32
-130     68/push  1/imm32/true
-131     50/push-eax
-132     # . . call
-133     e8/call  check-ints-equal/disp32
-134     # . . discard args
-135     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-136     c3/return
-137 
-138 test-compare-null-kernel-string-with-non-empty-array:
-139     # eax = kernel-string-equal?(Null-kernel-string, "Abc")
-140     # . . push args
-141     68/push  "Abc"/imm32
-142     68/push  Null-kernel-string/imm32
-143     # . . call
-144     e8/call  kernel-string-equal?/disp32
-145     # . . discard args
-146     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-147     # check-ints-equal(eax, 0, msg)
-148     # . . push args
-149     68/push  "F - test-compare-null-kernel-string-with-non-empty-array"/imm32
-150     68/push  0/imm32/false
-151     50/push-eax
-152     # . . call
-153     e8/call  check-ints-equal/disp32
-154     # . . discard args
-155     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-156     c3/return
-157 
-158 test-compare-kernel-string-with-equal-array:
-159     # eax = kernel-string-equal?(_test-Abc-kernel-string, "Abc")
-160     # . . push args
-161     68/push  "Abc"/imm32
-162     68/push  _test-Abc-kernel-string/imm32
-163     # . . call
-164     e8/call  kernel-string-equal?/disp32
-165     # . . discard args
-166     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-167     # check-ints-equal(eax, 1, msg)
-168     # . . push args
-169     68/push  "F - test-compare-kernel-string-with-equal-array"/imm32
-170     68/push  1/imm32/true
-171     50/push-eax
-172     # . . call
-173     e8/call  check-ints-equal/disp32
-174     # . . discard args
-175     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-176     c3/return
-177 
-178 test-compare-kernel-string-with-inequal-array:
-179     # eax = kernel-string-equal?(_test-Abc-kernel-string, "Adc")
-180     # . . push args
-181     68/push  "Adc"/imm32
-182     68/push  _test-Abc-kernel-string/imm32
-183     # . . call
-184     e8/call  kernel-string-equal?/disp32
-185     # . . discard args
-186     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-187     # check-ints-equal(eax, 0, msg)
-188     # . . push args
-189     68/push  "F - test-compare-kernel-string-with-equal-array"/imm32
-190     68/push  0/imm32/false
-191     50/push-eax
-192     # . . call
-193     e8/call  check-ints-equal/disp32
-194     # . . discard args
-195     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-196     c3/return
-197 
-198 test-compare-kernel-string-with-empty-array:
-199     # eax = kernel-string-equal?(_test-Abc-kernel-string, "")
-200     # . . push args
-201     68/push  ""/imm32
-202     68/push  _test-Abc-kernel-string/imm32
-203     # . . call
-204     e8/call  kernel-string-equal?/disp32
-205     # . . discard args
-206     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-207     # check-ints-equal(eax, 0, msg)
-208     # . . push args
-209     68/push  "F - test-compare-kernel-string-with-equal-array"/imm32
-210     68/push  0/imm32/false
-211     50/push-eax
-212     # . . call
-213     e8/call  check-ints-equal/disp32
-214     # . . discard args
-215     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-216     c3/return
-217 
-218 test-compare-kernel-string-with-shorter-array:
-219     # eax = kernel-string-equal?(_test-Abc-kernel-string, "Ab")
-220     # . . push args
-221     68/push  "Ab"/imm32
-222     68/push  _test-Abc-kernel-string/imm32
-223     # . . call
-224     e8/call  kernel-string-equal?/disp32
-225     # . . discard args
-226     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-227     # check-ints-equal(eax, 0, msg)
-228     # . . push args
-229     68/push  "F - test-compare-kernel-string-with-shorter-array"/imm32
-230     68/push  0/imm32/false
-231     50/push-eax
-232     # . . call
-233     e8/call  check-ints-equal/disp32
-234     # . . discard args
-235     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-236     c3/return
-237 
-238 test-compare-kernel-string-with-longer-array:
-239     # eax = kernel-string-equal?(_test-Abc-kernel-string, "Abcd")
-240     # . . push args
-241     68/push  "Abcd"/imm32
-242     68/push  _test-Abc-kernel-string/imm32
-243     # . . call
-244     e8/call  kernel-string-equal?/disp32
-245     # . . discard args
-246     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
-247     # check-ints-equal(eax, 0, msg)
-248     # . . push args
-249     68/push  "F - test-compare-kernel-string-with-longer-array"/imm32
-250     68/push  0/imm32/false
-251     50/push-eax
-252     # . . call
-253     e8/call  check-ints-equal/disp32
-254     # . . discard args
-255     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
-256     c3/return
-257 
-258 # - helpers
-259 
-260 # print msg to stderr if a != b, otherwise print "."
-261 check-ints-equal:  # (a : int, b : int, msg : (address array byte)) -> boolean
-262     # . prologue
-263     55/push-ebp
-264     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-265     # . save registers
-266     51/push-ecx
-267     53/push-ebx
-268     # load args into eax, ebx and ecx
-269     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   8/disp8         .                 # copy *(ebp+8) to eax
-270     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           3/r32/ebx   0xc/disp8       .                 # copy *(ebp+12) to ebx
-271     # if (eax == b/ebx) print('.') and return
-272     39/compare                      3/mod/direct    0/rm32/eax    .           .             .           3/r32/ebx   .               .                 # compare eax and ebx
-273     75/jump-if-unequal  $check-ints-equal:else/disp8
-274     # . write-stderr('.')
-275     # . . push args
-276     68/push  "."/imm32
-277     # . . call
-278     e8/call  write-stderr/disp32
-279     # . . discard args
-280     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-281     # . return
-282     eb/jump  $check-ints-equal:end/disp8
-283     # otherwise print(msg)
-284 $check-ints-equal:else:
-285     # copy msg into ecx
-286     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   0x10/disp8       .                # copy *(ebp+16) to ecx
-287     # print(ecx)
-288     # . . push args
-289     51/push-ecx
-290     # . . call
-291     e8/call  write-stderr/disp32
-292     # . . discard args
-293     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-294     # print newline
-295     # . . push args
-296     68/push  Newline/imm32
-297     # . . call
-298     e8/call  write-stderr/disp32
-299     # . . discard args
-300     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
-301 $check-ints-equal:end:
-302     # . restore registers
-303     5b/pop-to-ebx
-304     59/pop-to-ecx
-305     # end
-306     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-307     5d/pop-to-ebp
-308     c3/return
-309 
-310 write-stderr:  # s : (address array byte) -> <void>
-311     # . prologue
-312     55/push-ebp
-313     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
-314     # . save registers
-315     50/push-eax
-316     51/push-ecx
-317     52/push-edx
-318     53/push-ebx
-319     # syscall(write, 2/stderr, (data) s+4, (size) *s)
-320     # . . fd = 2 (stderr)
-321     bb/copy-to-ebx  2/imm32
-322     # . . x = s+4
-323     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   8/disp8         .                 # copy *(ebp+8) to ecx
-324     81          0/subop/add         3/mod/direct    1/rm32/ecx    .           .             .           .           .               4/imm32           # add to ecx
-325     # . . size = *s
-326     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           2/r32/edx   8/disp8         .                 # copy *(ebp+8) to edx
-327     8b/copy                         0/mod/indirect  2/rm32/edx    .           .             .           2/r32/edx   .               .                 # copy *edx to edx
-328     # . . syscall
-329     e8/call  syscall_write/disp32
-330     # . restore registers
-331     5b/pop-to-ebx
-332     5a/pop-to-edx
-333     59/pop-to-ecx
-334     58/pop-to-eax
-335     # . end
-336     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
-337     5d/pop-to-ebp
-338     c3/return
-339 
-340 == data
-341 
-342 Newline:
-343     # size
-344     1/imm32
-345     # data
-346     0a/newline
-347 
-348 # for kernel-string-equal tests
-349 Null-kernel-string:
-350     00/null
-351 
-352 _test-Abc-kernel-string:
-353     41/A 62/b 63/c 00/null
-354 
-355 # . . vim:nowrap:textwidth=0
-
- - - -- cgit 1.4.1-2-gfad0