From 6e181e7fd998a0d542cb531c929c905a243ea2f6 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 5 Feb 2019 23:30:12 -0800 Subject: 4953 --- html/subx/055trace.subx.html | 424 ------------------------------------------- 1 file changed, 424 deletions(-) delete mode 100644 html/subx/055trace.subx.html (limited to 'html/subx/055trace.subx.html') diff --git a/html/subx/055trace.subx.html b/html/subx/055trace.subx.html deleted file mode 100644 index ea9a152c..00000000 --- a/html/subx/055trace.subx.html +++ /dev/null @@ -1,424 +0,0 @@ - - - - -Mu - subx/055trace.subx - - - - - - - - - - -https://github.com/akkartik/mu/blob/master/subx/055trace.subx -
-  1 # primitives for emitting traces to a trace stream, and for tests to check the trace stream
-  2 #
-  3 # A trace stream looks like this:
-  4 #   read : int  # index that we've read until
-  5 #   write : int  # index at which writes go
-  6 #   data : (array byte)  # prefixed by length as usual
-  7 # In a real trace the data will be in a special segment set aside for the purpose.
-  8 #
-  9 # primitives for operating on traces:
- 10 #   - initialize-trace-stream (update global variable)
- 11 #   - trace: stream, string
- 12 #   - die: stream (exit(1) if using real trace)
- 13 #   - check-trace-contains: stream, string/line, string/message (scans only from stream's read pointer, prints message to stderr on failure, updates stream's read pointer)
- 14 #   - rewind-reads: stream (resets read pointer)
- 15 #   - scan-to-next-line: stream (advance read pointer past next newline)
- 16 #
- 17 # Traces are very fundamental, so many of the helpers we create here won't be
- 18 # used elsewhere; we'll switch to more bounds-checked variants. But here we get
- 19 # bounds-checking for free; we allocate a completely disjoint segment for trace
- 20 # data, and overflowing it will generate a page fault.
- 21 
- 22 == data
- 23 
- 24 # We'll save the address of the trace segment here.
- 25 Trace-stream:
- 26     00 00 00 00
- 27 
- 28 # Fake trace-stream for tests.
- 29 # Also illustrates the layout of the real trace-stream (segment).
- 30 _test-trace-stream:
- 31     # current write index
- 32     00 00 00 00
- 33     # current read index
- 34     00 00 00 00
- 35     # length (= 8)
- 36     08 00 00 00
- 37     # data
- 38     00 00 00 00 00 00 00 00  # 8 bytes
- 39 
- 40 == code
- 41 #   instruction                     effective address                                                   register    displacement    immediate
- 42 # . op          subop               mod             rm32          base        index         scale       r32
- 43 # . 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
- 44 
- 45 # main:
- 46     # run-tests()
- 47     e8/call  run-tests/disp32  # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
- 48     # syscall(exit, Num-test-failures)
- 49     8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Num-test-failures/disp32          # copy *Num-test-failures to EBX
- 50     b8/copy-to-EAX  1/imm32/exit
- 51     cd/syscall  0x80/imm8
- 52 
- 53 # Allocate a new segment for the trace stream, initialize its length, and save its address to Trace-stream.
- 54 # The Trace-stream segment will consist of variable-length lines separated by newlines (0x0a)
- 55 initialize-trace-stream:
- 56     # EAX = new-segment(0x1000)
- 57     # . . push args
- 58     68/push  0x1000/imm32/N
- 59     # . . call
- 60     e8/call  new-segment/disp32
- 61     # . . discard args
- 62     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
- 63     # copy EAX to *Trace-stream
- 64     89/copy                         0/mod/indirect  5/rm32/.disp32            .             .           0/r32/EAX   Trace-stream/disp32               # copy EAX to *Trace-stream
- 65     # Trace-stream->length = 0x1000/N - 12
- 66     c7          0/subop/copy        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           8/disp8         0xff4/imm32       # copy 0xff4 to *(EAX+8)
- 67     c3/return
- 68 
- 69 # Append a string to the given trace stream.
- 70 # Silently give up if it's already full. Or truncate the string if there isn't enough room.
- 71 trace:  # t : (address trace-stream), line : string
- 72     # . prolog
- 73     55/push-EBP
- 74     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
- 75     # . save registers
- 76     50/push-EAX
- 77     51/push-ECX
- 78     52/push-EDX
- 79     53/push-EBX
- 80     56/push-ESI
- 81     57/push-EDI
- 82     # EDI = t
- 83     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .                         7/r32/EDI   8/disp8         .                 # copy *(EBP+8) to EDI
- 84     # ESI = line
- 85     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .                         6/r32/ESI   0xc/disp8       .                 # copy *(EBP+12) to ESI
- 86     # ECX = t->write
- 87     8b/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           1/r32/ECX   .               .                 # copy *EDI to ECX
- 88     # EDX = t->length
- 89     8b/copy                         1/mod/*+disp8   7/rm32/EDI    .           .             .           2/r32/EDX   8/disp8         .                 # copy *(EDI+8) to EDX
- 90     # EAX = _append-3(&t->data[t->write], &t->data[t->length], line)
- 91     # . . push line
- 92     56/push-ESI
- 93     # . . push &t->data[t->length]
- 94     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    7/base/EDI  2/index/EDX   .           3/r32/EBX   0xc/disp8       .                 # copy EDI+EDX+12 to EBX
- 95     53/push-EBX
- 96     # . . push &t->data[t->write]
- 97     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    7/base/EDI  1/index/ECX   .           3/r32/EBX   0xc/disp8       .                 # copy EDI+ECX+12 to EBX
- 98     53/push-EBX
- 99     # . . call
-100     e8/call  _append-3/disp32
-101     # . . discard args
-102     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-103     # if EAX == 0 return
-104     81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # compare EDX
-105     74/jump-if-equal  $trace:end/disp8
-106     # t->write += EAX
-107     01/add                          0/mod/indirect  7/rm32/EDI    .           .             .           0/r32/EAX   .               .                 # add EAX to *EDI
-108     # refresh ECX = t->write
-109     8b/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           1/r32/ECX   .               .                 # copy *EDI to ECX
-110     # EAX = _append-3(&t->data[t->write], &t->data[t->length], line)
-111     # . . push line
-112     68/push  Newline/imm32
-113     # . . push &t->data[t->length]
-114     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    7/base/EDI  2/index/EDX   .           3/r32/EBX   0xc/disp8       .                 # copy EDI+EDX+12 to EBX
-115     53/push-EBX
-116     # . . push &t->data[t->write]
-117     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    7/base/EDI  1/index/ECX   .           3/r32/EBX   0xc/disp8       .                 # copy EDI+ECX+12 to EBX
-118     53/push-EBX
-119     # . . call
-120     e8/call  _append-3/disp32
-121     # . . discard args
-122     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-123     # t->write += EAX
-124     01/add                          0/mod/indirect  7/rm32/EDI    .           .             .           0/r32/EAX   .               .                 # add EAX to *EDI
-125 $trace:end:
-126     # . restore registers
-127     5f/pop-to-EDI
-128     5e/pop-to-ESI
-129     5b/pop-to-EBX
-130     5a/pop-to-EDX
-131     59/pop-to-ECX
-132     58/pop-to-EAX
-133     # . epilog
-134     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
-135     5d/pop-to-EBP
-136     c3/return
-137 
-138 clear-trace-stream:  # t : (address trace-stream)
-139     # . prolog
-140     55/push-EBP
-141     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-142     # . save registers
-143     50/push-EAX
-144     51/push-ECX
-145     # EAX = t
-146     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .                         0/r32/EAX   8/disp8         .                 # copy *(EBP+8) to EAX
-147     # ECX = t->length
-148     8b/copy                         1/mod/*+disp8   0/rm32/EAX    .           .             .           1/r32/ECX   8/disp8         .                 # copy *(EAX+8) to ECX
-149     # ECX = &t->data[t->length]
-150     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   0xc/disp8       .                 # copy EAX+ECX+12 to ECX
-151     # t->write = 0
-152     c7          0/subop/copy        0/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # copy to *EAX
-153     # t->read = 0
-154     c7          0/subop/copy        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           4/disp8         0/imm32           # copy to *(EAX+4)
-155     # EAX = t->data
-156     81          0/subop/add         3/mod/direct    0/rm32/EAX    .           .             .           .           .               0xc/imm32         # add to EAX
-157     # while (true)
-158 $clear-trace-stream:loop:
-159     # if EAX >= ECX break
-160     39/compare                      3/mod/direct    0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # compare EAX with ECX
-161     7d/jump-if-greater-or-equal  $clear-trace-stream:end/disp8
-162     # *EAX = 0
-163     c7          0/subop/copy        0/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # copy to *EAX
-164     # EAX += 4
-165     81          0/subop/add         3/mod/direct    0/rm32/EAX    .           .             .           .           .               4/imm32           # add to EAX
-166     eb/jump  $clear-trace-stream:loop/disp8
-167 $clear-trace-stream:end:
-168     # . restore registers
-169     59/pop-to-ECX
-170     58/pop-to-EAX
-171     # . epilog
-172     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
-173     5d/pop-to-EBP
-174     c3/return
-175 
-176 # - tests
-177 
-178 test-trace-single:
-179     # clear-trace-stream(_test-trace-stream)
-180     # . . push args
-181     68/push  _test-trace-stream/imm32
-182     # . . call
-183     e8/call  clear-trace-stream/disp32
-184     # . . discard args
-185     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-186     # trace(_test-trace-stream, "Ab")
-187     # . . push args
-188     68/push  "Ab"/imm32
-189     68/push  _test-trace-stream/imm32
-190     # . . call
-191     e8/call  trace/disp32
-192     # . . discard args
-193     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-194     # check-ints-equal(*_test-trace-stream->data, 41/A 62/b 0a/newline 00, msg)
-195     # . . push args
-196     68/push  "F - test-trace-single"/imm32
-197     68/push  0x0a6241/imm32/Ab-newline
-198     # . . push *_test-trace-stream->data
-199     b8/copy-to-EAX  _test-trace-stream/imm32
-200     ff          6/subop/push        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           0xc/disp8       .                 # push *(EAX+12)
-201     # . . call
-202     e8/call  check-ints-equal/disp32
-203     # . . discard args
-204     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-205     # end
-206     c3/return
-207 
-208 test-trace-appends:
-209     # clear-trace-stream(_test-trace-stream)
-210     # . . push args
-211     68/push  _test-trace-stream/imm32
-212     # . . call
-213     e8/call  clear-trace-stream/disp32
-214     # . . discard args
-215     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-216     # trace(_test-trace-stream, "C")
-217     # . . push args
-218     68/push  "C"/imm32
-219     68/push  _test-trace-stream/imm32
-220     # . . call
-221     e8/call  trace/disp32
-222     # . . discard args
-223     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-224     # trace(_test-trace-stream, "D")
-225     # . . push args
-226     68/push  "D"/imm32
-227     68/push  _test-trace-stream/imm32
-228     # . . call
-229     e8/call  trace/disp32
-230     # . . discard args
-231     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-232     # check-ints-equal(*_test-trace-stream->data, 43/C 0a/newline 44/D 0a/newline, msg)
-233     # . . push args
-234     68/push  "F - test-trace-appends"/imm32
-235     68/push  0x0a440a43/imm32/C-newline-D-newline
-236     # . . push *_test-trace-stream->data
-237     b8/copy-to-EAX  _test-trace-stream/imm32
-238     ff          6/subop/push        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           0xc/disp8       .                 # push *(EAX+12)
-239     # . . call
-240     e8/call  check-ints-equal/disp32
-241     # . . discard args
-242     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-243     # end
-244     c3/return
-245 
-246 test-trace-empty-line:
-247     # clear-trace-stream(_test-trace-stream)
-248     # . . push args
-249     68/push  _test-trace-stream/imm32
-250     # . . call
-251     e8/call  clear-trace-stream/disp32
-252     # . . discard args
-253     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
-254     # trace(_test-trace-stream, "")
-255     # . . push args
-256     68/push  ""/imm32
-257     68/push  _test-trace-stream/imm32
-258     # . . call
-259     e8/call  trace/disp32
-260     # . . discard args
-261     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-262     # check-ints-equal(*_test-trace-stream->data, 0, msg)
-263     # . . push args
-264     68/push  "F - test-trace-empty-line"/imm32
-265     68/push  0/imm32
-266     # . . push *_test-trace-stream->data
-267     b8/copy-to-EAX  _test-trace-stream/imm32
-268     ff          6/subop/push        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           0xc/disp8       .                 # push *(EAX+12)
-269     # . . call
-270     e8/call  check-ints-equal/disp32
-271     # . . discard args
-272     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-273     # end
-274     c3/return
-275 
-276 # - helpers
-277 
-278 # 3-argument variant of _append
-279 _append-3:  # out : address, outend : address, s : (array byte) -> num_bytes_appended/EAX
-280     # . prolog
-281     55/push-EBP
-282     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-283     # . save registers
-284     51/push-ECX
-285     # _append-4(out, outend, &s->data[0], &s->data[s->length]) -> num_bytes_appended/EAX
-286     # . . push &s->data[s->length]
-287     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .                         0/r32/EAX   0x10/disp8      .                 # copy *(EBP+16) to EAX
-288     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
-289     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/EAX  1/index/ECX   .           1/r32/ECX   4/disp8         .                 # copy EAX+ECX+4 to ECX
-290     51/push-ECX
-291     # . . push &s->data[0]
-292     8d/copy-address                 1/mod/*+disp8   0/rm32/EAX    .           .             .           1/r32/ECX   4/disp8         .                 # copy EAX+4 to ECX
-293     51/push-ECX
-294     # . . push outend
-295     ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
-296     # . . push out
-297     ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
-298     # . . call
-299     e8/call  _append-4/disp32
-300     # . . discard args
-301     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0x10/imm32        # add to ESP
-302 $_append-3:end:
-303     # . restore registers
-304     59/pop-to-ECX
-305     # . epilog
-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 # 4-argument variant of _append
-311 _append-4:  # out : address, outend : address, in : address, inend : address -> num_bytes_appended/EAX
-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     51/push-ECX
-317     52/push-EDX
-318     53/push-EBX
-319     56/push-ESI
-320     57/push-EDI
-321     # EAX/num_bytes_appended = 0
-322     b8/copy-to-EAX  0/imm32
-323     # EDI = out
-324     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           7/r32/EDI   8/disp8         .                 # copy *(EBP+8) to EDI
-325     # EDX = outend
-326     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           2/r32/EDX   0xc/disp8       .                 # copy *(EBP+12) to EDX
-327     # ESI = in
-328     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           6/r32/ESI   0x10/disp8      .                 # copy *(EBP+16) to ESI
-329     # ECX = inend
-330     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           1/r32/ECX   0x14/disp8      .                 # copy *(EBP+20) to ECX
-331 $_append-4:loop:
-332     # if ESI/in >= ECX/inend break
-333     39/compare                      3/mod/direct    6/rm32/ESI    .           .             .           1/r32/ECX   .               .                 # compare ESI with ECX
-334     7d/jump-if-greater-or-equal  $_append-4:end/disp8
-335     # if EDI/out >= EDX/outend break  (for now silently ignore filled up buffer)
-336     39/compare                      3/mod/direct    7/rm32/EDI    .           .             .           2/r32/EDX   .               .                 # compare EDI with EDX
-337     7d/jump-if-greater-or-equal  $_append-4:end/disp8
-338     # copy one byte from ESI/in to EDI/out
-339     8a/copy-byte                    0/mod/indirect  6/rm32/ESI    .           .             .           3/r32/BL    .               .                 # copy byte at *ESI to BL
-340     88/copy-byte                    0/mod/indirect  7/rm32/EDI    .           .             .           3/r32/BL    .               .                 # copy byte at BL to *EDI
-341     # updates
-342     40/increment-EAX
-343     46/increment-ESI
-344     47/increment-EDI
-345     eb/jump  $_append-4:loop/disp8
-346 $_append-4:end:
-347     # . restore registers
-348     5f/pop-to-EDI
-349     5e/pop-to-ESI
-350     5b/pop-to-EBX
-351     5a/pop-to-EDX
-352     59/pop-to-ECX
-353     # . epilog
-354     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
-355     5d/pop-to-EBP
-356     c3/return
-357 
-358 # . . vim:nowrap:textwidth=0
-
- - - -- cgit 1.4.1-2-gfad0