From 3350c34a74844e21ea69077e01efff3bae64bdcd Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 23 Mar 2021 17:31:08 -0700 Subject: . --- html/linux/assort.subx.html | 762 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 762 insertions(+) create mode 100644 html/linux/assort.subx.html (limited to 'html/linux/assort.subx.html') diff --git a/html/linux/assort.subx.html b/html/linux/assort.subx.html new file mode 100644 index 00000000..a9322970 --- /dev/null +++ b/html/linux/assort.subx.html @@ -0,0 +1,762 @@ + + + + +Mu - linux/assort.subx + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/assort.subx +
+   1 # Read a series of segments from stdin and concatenate segments with the same
+   2 # name on stdout.
+   3 #
+   4 # Segments are emitted in order of first encounter.
+   5 #
+   6 # Drop lines that are all comments. They could get misleading after assortment
+   7 # because we don't know if they refer to the line above or the line below.
+   8 #
+   9 # To run:
+  10 #   $ bootstrap/bootstrap translate [01]*.subx apps/subx-params.subx apps/assort.subx  -o apps/assort
+  11 #   $ cat x
+  12 #   == code
+  13 #   abc
+  14 #   == code
+  15 #   def
+  16 #   $ cat x  |bootstrap/bootstrap run assort
+  17 #   == code
+  18 #   abc
+  19 #   def
+  20 
+  21 == code
+  22 #   instruction                     effective address                                                   register    displacement    immediate
+  23 # . op          subop               mod             rm32          base        index         scale       r32
+  24 # . 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
+  25 
+  26 Entry:  # run tests if necessary, convert stdin if not
+  27     # . prologue
+  28     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+  29 
+  30     # initialize heap
+  31     # . Heap = new-segment(Heap-size)
+  32     # . . push args
+  33     68/push  Heap/imm32
+  34     ff          6/subop/push        0/mod/indirect  5/rm32/.disp32            .             .           .           Heap-size/disp32                  # push *Heap-size
+  35     # . . call
+  36     e8/call  new-segment/disp32
+  37     # . . discard args
+  38     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+  39 
+  40     # - if argc > 1 and argv[1] == "test", then return run_tests()
+  41     # if (argc <= 1) goto interactive
+  42     81          7/subop/compare     1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0/disp8         1/imm32           # compare *ebp
+  43     7e/jump-if-<=  $subx-assort-main:interactive/disp8
+  44     # if (!kernel-string-equal?(argv[1], "test")) goto interactive
+  45     # . eax = kernel-string-equal?(argv[1], "test")
+  46     # . . push args
+  47     68/push  "test"/imm32
+  48     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
+  49     # . . call
+  50     e8/call  kernel-string-equal?/disp32
+  51     # . . discard args
+  52     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+  53     # . if (eax == false) goto interactive
+  54     3d/compare-eax-and  0/imm32/false
+  55     74/jump-if-=  $subx-assort-main:interactive/disp8
+  56     # run-tests()
+  57     e8/call  run-tests/disp32
+  58     # syscall(exit, *Num-test-failures)
+  59     8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/ebx   Num-test-failures/disp32          # copy *Num-test-failures to ebx
+  60     eb/jump  $subx-assort-main:end/disp8
+  61 $subx-assort-main:interactive:
+  62     # - otherwise convert stdin
+  63     # var ed/eax: exit-descriptor
+  64     81          5/subop/subtract    3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # subtract from esp
+  65     89/copy                         3/mod/direct    0/rm32/eax    .           .             .           4/r32/esp   .               .                 # copy esp to eax
+  66     # configure ed to really exit()
+  67     # . ed->target = 0
+  68     c7          0/subop/copy        0/mod/direct    0/rm32/eax    .           .             .           .           .               0/imm32           # copy to *eax
+  69     # subx-assort(Stdin, Stdout, Stderr, ed)
+  70     # . . push args
+  71     50/push-eax/ed
+  72     68/push  Stderr/imm32
+  73     68/push  Stdout/imm32
+  74     68/push  Stdin/imm32
+  75     # . . call
+  76     e8/call  subx-assort/disp32
+  77     # . . discard args
+  78     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0x10/imm32        # add to esp
+  79     # syscall(exit, 0)
+  80     bb/copy-to-ebx  0/imm32
+  81 $subx-assort-main:end:
+  82     e8/call  syscall_exit/disp32
+  83 
+  84 # data structure:
+  85 #   table: (addr stream {(handle array byte), (handle stream byte)})     (16 bytes/row)
+  86 # inefficient; uses sequential search for looking up segments by name
+  87 
+  88 subx-assort:  # in: (addr buffered-file), out: (addr buffered-file)
+  89     # pseudocode:
+  90     #   var table: (addr stream {(handle array byte), (handle stream byte)} 10 rows)
+  91     #   read-segments(in, table)
+  92     #   write-segments(out, table)
+  93     #
+  94     # . prologue
+  95     55/push-ebp
+  96     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+  97     # . save registers
+  98     51/push-ecx
+  99     # var table/ecx: (stream {string, (handle stream byte)} 160)  # 10 rows * 16 bytes/row
+ 100     81          5/subop/subtract    3/mod/direct    4/rm32/esp    .           .             .           .           .               0xa0/imm32        # subtract from esp
+ 101     68/push  0xa0/imm32/length
+ 102     68/push  0/imm32/read
+ 103     68/push  0/imm32/write
+ 104     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+ 105     # clear-stream(table)
+ 106     # . . push args
+ 107     51/push-ecx
+ 108     # . . call
+ 109     e8/call  clear-stream/disp32
+ 110     # . . discard args
+ 111     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+ 112 $subx-assort:read:
+ 113 +--  9 lines: #?     # print("read\n") --------------------------------------------------------------------------------------------------------------------------------------------------
+ 122     # read-segments(in, table)
+ 123     # . . push args
+ 124     51/push-ecx
+ 125     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
+ 126     # . . call
+ 127     e8/call  read-segments/disp32
+ 128     # . . discard args
+ 129     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 130 $subx-assort:write:
+ 131 +--  9 lines: #?     # print("write\n") -------------------------------------------------------------------------------------------------------------------------------------------------
+ 140     # write-segments(out, table)
+ 141     # . . push args
+ 142     51/push-ecx
+ 143     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
+ 144     # . . call
+ 145     e8/call  write-segments/disp32
+ 146     # . . discard args
+ 147     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 148 $subx-assort:end:
+ 149     # . reclaim locals
+ 150     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xac/imm32        # add to esp
+ 151     # . restore registers
+ 152     59/pop-to-ecx
+ 153     # . epilogue
+ 154     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+ 155     5d/pop-to-ebp
+ 156     c3/return
+ 157 
+ 158 test-subx-assort:
+ 159     # . prologue
+ 160     55/push-ebp
+ 161     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+ 162     # setup
+ 163     # . clear-stream(_test-input-stream)
+ 164     # . . push args
+ 165     68/push  _test-input-stream/imm32
+ 166     # . . call
+ 167     e8/call  clear-stream/disp32
+ 168     # . . discard args
+ 169     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+ 170     # . clear-stream($_test-input-buffered-file->buffer)
+ 171     # . . push args
+ 172     68/push  $_test-input-buffered-file->buffer/imm32
+ 173     # . . call
+ 174     e8/call  clear-stream/disp32
+ 175     # . . discard args
+ 176     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+ 177     # . clear-stream(_test-output-stream)
+ 178     # . . push args
+ 179     68/push  _test-output-stream/imm32
+ 180     # . . call
+ 181     e8/call  clear-stream/disp32
+ 182     # . . discard args
+ 183     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+ 184     # . clear-stream($_test-output-buffered-file->buffer)
+ 185     # . . push args
+ 186     68/push  $_test-output-buffered-file->buffer/imm32
+ 187     # . . call
+ 188     e8/call  clear-stream/disp32
+ 189     # . . discard args
+ 190     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+ 191     # initialize input (meta comments in parens)
+ 192     #   # comment 1
+ 193     #     # comment 2 indented
+ 194     #   == code 0x09000000  (new segment)
+ 195     #   # comment 3 inside a segment
+ 196     #   1
+ 197     #                         (empty line)
+ 198     #   2 3 # comment 4 inline with other contents
+ 199     #   == data 0x0a000000  (new segment)
+ 200     #   4 5/imm32
+ 201     #   == code  (existing segment but non-contiguous with previous iteration)
+ 202     #   6 7
+ 203     #   8 9  (multiple lines)
+ 204     #   == code  (existing segment contiguous with previous iteration)
+ 205     #   10 11
+ 206     # . write(_test-input-stream, "# comment 1\n")
+ 207     # . . push args
+ 208     68/push  "# comment 1\n"/imm32
+ 209     68/push  _test-input-stream/imm32
+ 210     # . . call
+ 211     e8/call  write/disp32
+ 212     # . . discard args
+ 213     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 214     # . write(_test-input-stream, "  # comment 2 indented\n")
+ 215     # . . push args
+ 216     68/push  "  # comment 2 indented\n"/imm32
+ 217     68/push  _test-input-stream/imm32
+ 218     # . . call
+ 219     e8/call  write/disp32
+ 220     # . . discard args
+ 221     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 222     # . write(_test-input-stream, "== code 0x09000000\n")
+ 223     # . . push args
+ 224     68/push  "== code 0x09000000\n"/imm32
+ 225     68/push  _test-input-stream/imm32
+ 226     # . . call
+ 227     e8/call  write/disp32
+ 228     # . . discard args
+ 229     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 230     # . write(_test-input-stream, "# comment 3 inside a segment\n")
+ 231     # . . push args
+ 232     68/push  "# comment 3 inside a segment\n"/imm32
+ 233     68/push  _test-input-stream/imm32
+ 234     # . . call
+ 235     e8/call  write/disp32
+ 236     # . . discard args
+ 237     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 238     # . write(_test-input-stream, "1\n")
+ 239     # . . push args
+ 240     68/push  "1\n"/imm32
+ 241     68/push  _test-input-stream/imm32
+ 242     # . . call
+ 243     e8/call  write/disp32
+ 244     # . . discard args
+ 245     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 246     # . write(_test-input-stream, "\n")  # empty line
+ 247     # . . push args
+ 248     68/push  Newline/imm32
+ 249     68/push  _test-input-stream/imm32
+ 250     # . . call
+ 251     e8/call  write/disp32
+ 252     # . . discard args
+ 253     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 254     # . write(_test-input-stream, "2 3 # comment 4 inline with other contents\n")
+ 255     # . . push args
+ 256     68/push  "2 3 # comment 4 inline with other contents\n"/imm32
+ 257     68/push  _test-input-stream/imm32
+ 258     # . . call
+ 259     e8/call  write/disp32
+ 260     # . . discard args
+ 261     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 262     # . write(_test-input-stream, "== data 0x0a000000\n")
+ 263     # . . push args
+ 264     68/push  "== data 0x0a000000\n"/imm32
+ 265     68/push  _test-input-stream/imm32
+ 266     # . . call
+ 267     e8/call  write/disp32
+ 268     # . . discard args
+ 269     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 270     # . write(_test-input-stream, "4 5/imm32\n")
+ 271     # . . push args
+ 272     68/push  "4 5/imm32\n"/imm32
+ 273     68/push  _test-input-stream/imm32
+ 274     # . . call
+ 275     e8/call  write/disp32
+ 276     # . . discard args
+ 277     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 278     # . write(_test-input-stream, "== code\n")
+ 279     # . . push args
+ 280     68/push  "== code\n"/imm32
+ 281     68/push  _test-input-stream/imm32
+ 282     # . . call
+ 283     e8/call  write/disp32
+ 284     # . . discard args
+ 285     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 286     # . write(_test-input-stream, "6 7\n")
+ 287     # . . push args
+ 288     68/push  "6 7\n"/imm32
+ 289     68/push  _test-input-stream/imm32
+ 290     # . . call
+ 291     e8/call  write/disp32
+ 292     # . . discard args
+ 293     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 294     # . write(_test-input-stream, "8 9\n")
+ 295     # . . push args
+ 296     68/push  "8 9\n"/imm32
+ 297     68/push  _test-input-stream/imm32
+ 298     # . . call
+ 299     e8/call  write/disp32
+ 300     # . . discard args
+ 301     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 302     # . write(_test-input-stream, "== code\n")
+ 303     # . . push args
+ 304     68/push  "== code\n"/imm32
+ 305     68/push  _test-input-stream/imm32
+ 306     # . . call
+ 307     e8/call  write/disp32
+ 308     # . . discard args
+ 309     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 310     # . write(_test-input-stream, "10 11\n")
+ 311     # . . push args
+ 312     68/push  "10 11\n"/imm32
+ 313     68/push  _test-input-stream/imm32
+ 314     # . . call
+ 315     e8/call  write/disp32
+ 316     # . . discard args
+ 317     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 318     # subx-assort(_test-input-buffered-file, _test-output-buffered-file)
+ 319     # . . push args
+ 320     68/push  _test-output-buffered-file/imm32
+ 321     68/push  _test-input-buffered-file/imm32
+ 322     # . . call
+ 323     e8/call  subx-assort/disp32
+ 324     # . . discard args
+ 325     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 326     # . flush(_test-output-buffered-file)
+ 327     # . . push args
+ 328     68/push  _test-output-buffered-file/imm32
+ 329     # . . call
+ 330     e8/call  flush/disp32
+ 331     # . . discard args
+ 332     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+ 333     # check output
+ 334     #   == code 0x09000000
+ 335     #   1
+ 336     #   2 3 # comment 4 inline with other contents
+ 337     #   6 7
+ 338     #   8 9
+ 339     #   10 11
+ 340     #   == data 0x0a000000
+ 341     #   4 5/imm32
+ 342 +-- 33 lines: #?     # dump output ------------------------------------------------------------------------------------------------------------------------------------------------------
+ 375     # . check-next-stream-line-equal(_test-output-stream, "== code 0x09000000", msg)
+ 376     # . . push args
+ 377     68/push  "F - test-subx-assort/0"/imm32
+ 378     68/push  "== code 0x09000000"/imm32
+ 379     68/push  _test-output-stream/imm32
+ 380     # . . call
+ 381     e8/call  check-next-stream-line-equal/disp32
+ 382     # . . discard args
+ 383     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+ 384     # . check-next-stream-line-equal(_test-output-stream, "1", msg)
+ 385     # . . push args
+ 386     68/push  "F - test-subx-assort/1"/imm32
+ 387     68/push  "1"/imm32
+ 388     68/push  _test-output-stream/imm32
+ 389     # . . call
+ 390     e8/call  check-next-stream-line-equal/disp32
+ 391     # . . discard args
+ 392     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+ 393     # . check-next-stream-line-equal(_test-output-stream, "2 3 # comment 4 inline with other contents", msg)
+ 394     # . . push args
+ 395     68/push  "F - test-subx-assort/2"/imm32
+ 396     68/push  "2 3 # comment 4 inline with other contents"/imm32
+ 397     68/push  _test-output-stream/imm32
+ 398     # . . call
+ 399     e8/call  check-next-stream-line-equal/disp32
+ 400     # . . discard args
+ 401     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+ 402     # . check-next-stream-line-equal(_test-output-stream, "6 7", msg)
+ 403     # . . push args
+ 404     68/push  "F - test-subx-assort/3"/imm32
+ 405     68/push  "6 7"/imm32
+ 406     68/push  _test-output-stream/imm32
+ 407     # . . call
+ 408     e8/call  check-next-stream-line-equal/disp32
+ 409     # . . discard args
+ 410     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+ 411     # . check-next-stream-line-equal(_test-output-stream, "8 9", msg)
+ 412     # . . push args
+ 413     68/push  "F - test-subx-assort/4"/imm32
+ 414     68/push  "8 9"/imm32
+ 415     68/push  _test-output-stream/imm32
+ 416     # . . call
+ 417     e8/call  check-next-stream-line-equal/disp32
+ 418     # . . discard args
+ 419     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+ 420     # . check-next-stream-line-equal(_test-output-stream, "10 11", msg)
+ 421     # . . push args
+ 422     68/push  "F - test-subx-assort/5"/imm32
+ 423     68/push  "10 11"/imm32
+ 424     68/push  _test-output-stream/imm32
+ 425     # . . call
+ 426     e8/call  check-next-stream-line-equal/disp32
+ 427     # . . discard args
+ 428     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+ 429     # . check-next-stream-line-equal(_test-output-stream, "== data 0x0a000000", msg)
+ 430     # . . push args
+ 431     68/push  "F - test-subx-assort/6"/imm32
+ 432     68/push  "== data 0x0a000000"/imm32
+ 433     68/push  _test-output-stream/imm32
+ 434     # . . call
+ 435     e8/call  check-next-stream-line-equal/disp32
+ 436     # . . discard args
+ 437     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+ 438     # . check-next-stream-line-equal(_test-output-stream, "4 5/imm32", msg)
+ 439     # . . push args
+ 440     68/push  "F - test-subx-assort/7"/imm32
+ 441     68/push  "4 5/imm32"/imm32
+ 442     68/push  _test-output-stream/imm32
+ 443     # . . call
+ 444     e8/call  check-next-stream-line-equal/disp32
+ 445     # . . discard args
+ 446     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+ 447     # . epilogue
+ 448     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+ 449     5d/pop-to-ebp
+ 450     c3/return
+ 451 
+ 452 read-segments:  # in: (addr buffered-file), table: (addr stream {(handle array byte), (handle stream byte)})
+ 453     # pseudocode:
+ 454     #   var curr-segment: (addr stream byte) = 0
+ 455     #   var line: (stream byte 512)
+ 456     #   while true
+ 457     #     clear-stream(line)
+ 458     #     read-line-buffered(in, line)
+ 459     #     if (line->write == 0) break             # end of file
+ 460     #     var word-slice = next-word-or-string(line)
+ 461     #     if slice-empty?(word-slice)             # whitespace
+ 462     #       continue
+ 463     #     if slice-starts-with?(word-slice, "#")  # comment
+ 464     #       continue
+ 465     #     if slice-equal?(word-slice, "==")
+ 466     #       var segment-name = next-word-or-string(line)
+ 467     #       var segment-slot: (addr handle stream byte) = get-or-insert-slice(table, segment-name, row-size=16)
+ 468     #       if *segment-slot != 0
+ 469     #         curr-segment = lookup(*segment-slot)
+ 470     #         continue
+ 471     #       new-stream(Heap, Segment-size, 1, segment-slot)
+ 472     #       curr-segment = lookup(*segment-slot)
+ 473     #     rewind-stream(line)
+ 474     #     write-stream(curr-segment, line)  # abort if curr-segment overflows
+ 475     #
+ 476     # word-slice and segment-name are both slices with disjoint lifetimes, so
+ 477     # we'll use the same address for them.
+ 478     #
+ 479     # registers:
+ 480     #   line: ecx
+ 481     #   word-slice and segment-name: edx
+ 482     #   segment-name and curr-segment: ebx
+ 483     #   word-slice->start: esi
+ 484     #   temporary: eax
+ 485     #
+ 486     # . prologue
+ 487     55/push-ebp
+ 488     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+ 489     # . save registers
+ 490     50/push-eax
+ 491     51/push-ecx
+ 492     52/push-edx
+ 493     53/push-ebx
+ 494     56/push-esi
+ 495     57/push-edi
+ 496     # var line/ecx: (stream byte 512)
+ 497     81          5/subop/subtract    3/mod/direct    4/rm32/esp    .           .             .           .           .               0x200/imm32       # subtract from esp
+ 498     68/push  0x200/imm32/length
+ 499     68/push  0/imm32/read
+ 500     68/push  0/imm32/write
+ 501     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+ 502     # var word-slice/edx: slice
+ 503     68/push  0/imm32/end
+ 504     68/push  0/imm32/start
+ 505     89/copy                         3/mod/direct    2/rm32/edx    .           .             .           4/r32/esp   .               .                 # copy esp to edx
+ 506 $read-segments:loop:
+ 507     # clear-stream(line)
+ 508     # . . push args
+ 509     51/push-ecx
+ 510     # . . call
+ 511     e8/call  clear-stream/disp32
+ 512     # . . discard args
+ 513     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+ 514     # read-line-buffered(in, line)
+ 515     # . . push args
+ 516     51/push-ecx
+ 517     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
+ 518     # . . call
+ 519     e8/call  read-line-buffered/disp32
+ 520     # . . discard args
+ 521     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 522 $read-segments:check0:
+ 523     # if (line->write == 0) break
+ 524     81          7/subop/compare     0/mod/indirect  1/rm32/ecx    .           .             .           .           .               0/imm32           # compare *ecx
+ 525     0f 84/jump-if-=  $read-segments:break/disp32
+ 526 +-- 33 lines: #?     # dump line --------------------------------------------------------------------------------------------------------------------------------------------------------
+ 559     # next-word-or-string(line, word-slice)
+ 560     # . . push args
+ 561     52/push-edx
+ 562     51/push-ecx
+ 563     # . . call
+ 564     e8/call  next-word-or-string/disp32
+ 565     # . . discard args
+ 566     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 567 $read-segments:check1:
+ 568 +--  9 lines: #?     # print("check1\n") ------------------------------------------------------------------------------------------------------------------------------------------------
+ 577     # if (slice-empty?(word-slice)) continue
+ 578     # . eax = slice-empty?(word-slice)
+ 579     # . . push args
+ 580     52/push-edx
+ 581     # . . call
+ 582     e8/call  slice-empty?/disp32
+ 583     # . . discard args
+ 584     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+ 585     # . if (eax != false) continue
+ 586     3d/compare-eax-and  0/imm32/false
+ 587     0f 85/jump-if-!=  $read-segments:loop/disp32
+ 588 $read-segments:check-for-comment:
+ 589 +--  9 lines: #?     # print("check for comment\n") -------------------------------------------------------------------------------------------------------------------------------------
+ 598     # if (slice-starts-with?(word-slice, "#")) continue
+ 599     # . var start/esi: (addr byte) = word-slice->start
+ 600     8b/copy                         0/mod/indirect  2/rm32/edx    .           .             .           6/r32/esi   .               .                 # copy *ecx to esi
+ 601     # . var c/eax: byte = *start
+ 602     31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
+ 603     8a/copy-byte                    0/mod/indirect  6/rm32/esi    .           .             .           0/r32/AL    .               .                 # copy byte at *esi to AL
+ 604     # . if (c == '#') continue
+ 605     3d/compare-eax-and  0x23/imm32/hash
+ 606     0f 84/jump-if-=  $read-segments:loop/disp32
+ 607 $read-segments:check-for-segment-header:
+ 608 +--  9 lines: #?     # print("check for segment header\n") ------------------------------------------------------------------------------------------------------------------------------
+ 617 +-- 40 lines: #?     # dump word-slice --------------------------------------------------------------------------------------------------------------------------------------------------
+ 657     # if !slice-equal?(word-slice, "==") goto next check
+ 658     # . eax = slice-equal?(word-slice, "==")
+ 659     # . . push args
+ 660     68/push  "=="/imm32
+ 661     52/push-edx
+ 662     # . . call
+ 663     e8/call  slice-equal?/disp32
+ 664     # . . discard args
+ 665     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 666     # . if (eax == false) goto next check
+ 667     3d/compare-eax-and  0/imm32/false
+ 668     0f 84/jump-if-=  $read-segments:regular-line/disp32
+ 669     # segment-name = next-word-or-string(line)
+ 670     # . . push args
+ 671     52/push-edx
+ 672     51/push-ecx
+ 673     # . . call
+ 674     e8/call  next-word-or-string/disp32
+ 675     # . . discard args
+ 676     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 677 +-- 40 lines: #?     # dump segment name ------------------------------------------------------------------------------------------------------------------------------------------------
+ 717     # var segment-slot/edi: (addr handle stream byte) = get-or-insert-slice(table, segment-name, row-size=16, Heap)
+ 718     # . eax = get-or-insert-slice(table, segment-name, row-size=16, Heap)
+ 719     # . . push args
+ 720     68/push  Heap/imm32
+ 721     68/push  0x10/imm32/row-size
+ 722     52/push-edx
+ 723     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
+ 724     # . . call
+ 725     e8/call  get-or-insert-slice/disp32
+ 726     # . . discard args
+ 727     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0x10/imm32        # add to esp
+ 728     # . edi = eax
+ 729     89/copy                         3/mod/direct    7/rm32/edi    .           .             .           0/r32/eax   .               .                 # copy eax to edi
+ 730 +-- 33 lines: #?     # print("slot: " segment-slot "\n") --------------------------------------------------------------------------------------------------------------------------------
+ 763     # if (*segment-slot != 0) update curr-segment and continue
+ 764     81          7/subop/compare     0/mod/indirect  7/rm32/edi    .           .             .           .           .               0/imm32           # compare edi
+ 765     0f 84/jump-if-=  $read-segments:create-segment/disp32
+ 766     # var curr-segment/ebx: (addr stream byte) = lookup(*segment-slot)
+ 767     # . eax = lookup(*segment-slot)
+ 768     # . . push args
+ 769     ff          6/subop/push        1/mod/*+disp8   7/rm32/edi    .           .             .           .           4/disp8         .                 # push *(edi+4)
+ 770     ff          6/subop/push        0/mod/indirect  7/rm32/edi    .           .             .           .           .               .                 # push *edi
+ 771     # . . call
+ 772     e8/call  lookup/disp32
+ 773     # . . discard args
+ 774     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 775     # . ebx = eax
+ 776     89/copy                         3/mod/direct    3/rm32/ebx    .           .             .           0/r32/eax   .               .                 # copy eax to ebx
+ 777     # continue
+ 778     e9/jump  $read-segments:loop/disp32
+ 779 $read-segments:create-segment:
+ 780     # new-stream(Heap, Segment-size, 1, segment-slot)
+ 781     # . . push args
+ 782     57/push-edi
+ 783     68/push  1/imm32
+ 784     ff          6/subop/push        0/mod/indirect  5/rm32/.disp32            .             .           .           Segment-size/disp32               # push *Segment-size
+ 785     68/push  Heap/imm32
+ 786     # . . call
+ 787     e8/call  new-stream/disp32
+ 788     # . . discard args
+ 789     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0x10/imm32        # add to esp
+ 790     # var curr-segment/ebx: (addr stream byte) = lookup(*segment-slot)
+ 791     # . eax = lookup(*segment-slot)
+ 792     # . . push args
+ 793     ff          6/subop/push        1/mod/*+disp8   7/rm32/edi    .           .             .           .           4/disp8         .                 # push *(edi+4)
+ 794     ff          6/subop/push        0/mod/indirect  7/rm32/edi    .           .             .           .           .               .                 # push *edi
+ 795     # . . call
+ 796     e8/call  lookup/disp32
+ 797     # . . discard args
+ 798     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 799     # . ebx = eax
+ 800     89/copy                         3/mod/direct    3/rm32/ebx    .           .             .           0/r32/eax   .               .                 # copy eax to ebx
+ 801     # fall through
+ 802 $read-segments:regular-line:
+ 803 +--  9 lines: #?     # print("regular line\n") ------------------------------------------------------------------------------------------------------------------------------------------
+ 812 +-- 33 lines: #?     # dump line --------------------------------------------------------------------------------------------------------------------------------------------------------
+ 845 +-- 33 lines: #?     # print("addr: " curr-segment->write "\n") -------------------------------------------------------------------------------------------------------------------------
+ 878 +-- 33 lines: #?     # print("write: " curr-segment->write "\n") ------------------------------------------------------------------------------------------------------------------------
+ 911 +-- 33 lines: #?     # print("size: " curr-segment->size "\n") --------------------------------------------------------------------------------------------------------------------------
+ 944     # rewind-stream(line)
+ 945     # . . push args
+ 946     51/push-ecx
+ 947     # . . call
+ 948     e8/call  rewind-stream/disp32
+ 949     # . . discard args
+ 950     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+ 951 +--  9 lines: #?     # print("write stream\n") ------------------------------------------------------------------------------------------------------------------------------------------
+ 960     # write-stream(curr-segment, line)
+ 961     # . . push args
+ 962     51/push-ecx
+ 963     53/push-ebx
+ 964     # . . call
+ 965     e8/call  write-stream/disp32
+ 966     # . . discard args
+ 967     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 968     # loop
+ 969 +--  9 lines: #?     # print("loop\n") --------------------------------------------------------------------------------------------------------------------------------------------------
+ 978     e9/jump  $read-segments:loop/disp32
+ 979 $read-segments:break:
+ 980 $read-segments:end:
+ 981     # . reclaim locals
+ 982     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0x214/imm32       # add to esp
+ 983     # . restore registers
+ 984     5f/pop-to-edi
+ 985     5e/pop-to-esi
+ 986     5b/pop-to-ebx
+ 987     5a/pop-to-edx
+ 988     59/pop-to-ecx
+ 989     58/pop-to-eax
+ 990     # . epilogue
+ 991     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+ 992     5d/pop-to-ebp
+ 993     c3/return
+ 994 
+ 995 write-segments:  # out: (addr buffered-file), table: (addr stream {(handle array byte), (handle stream byte)})
+ 996     # pseudocode:
+ 997     #   var curr = table->data
+ 998     #   var max = &table->data[table->write]
+ 999     #   while curr < max
+1000     #     var stream: (addr stream byte) = lookup(table[i].stream)
+1001     #     write-stream-data(out, stream)
+1002     #     curr += 16
+1003     #   flush(out)
+1004     #
+1005     # . prologue
+1006     55/push-ebp
+1007     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+1008     # . save registers
+1009     50/push-eax
+1010     52/push-edx
+1011     56/push-esi
+1012     # esi = table
+1013     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   0xc/disp8       .                 # copy *(ebp+12) to esi
+1014     # var write/edx: int = table->write
+1015     8b/copy                         0/mod/indirect  6/rm32/esi    .           .             .           2/r32/edx   .               .                 # copy *esi to edx
+1016     # var curr/esi: (addr byte) = table->data
+1017     81          0/subop/add         3/mod/direct    6/rm32/esi    .           .             .           .           .               0xc/imm32         # add to eax
+1018     # var max/edx: (addr byte) = curr + write
+1019     01/add                          3/mod/direct    2/rm32/edx    .           .             .           6/r32/esi   .               .                 # add esi to edx
+1020 $write-segments:loop:
+1021     # if (curr >= max) break
+1022     39/compare                      3/mod/direct    6/rm32/esi    .           .             .           2/r32/edx   .               .                 # compare esi with edx
+1023     73/jump-if-addr>=  $write-segments:break/disp8
+1024     # var stream/eax: (addr stream byte) = lookup(table[i].stream)
+1025     # . . push args
+1026     ff          6/subop/push        1/mod/*+disp8   6/rm32/esi    .           .             .           .           0xc/disp8       .                 # push *(esi+12)
+1027     ff          6/subop/push        1/mod/*+disp8   6/rm32/esi    .           .             .           .           8/disp8         .                 # push *(esi+8)
+1028     # . . call
+1029     e8/call  lookup/disp32
+1030     # . . discard args
+1031     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+1032     # write-stream-data(out, stream)
+1033     # . . push args
+1034     50/push-eax
+1035     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
+1036     # . . call
+1037     e8/call  write-stream-data/disp32
+1038     # . . discard args
+1039     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+1040 $write-segments:continue:
+1041     # curr += 16
+1042     81          0/subop/add         3/mod/direct    6/rm32/esi    .           .             .           .           .               0x10/imm32        # add to esi
+1043     eb/jump  $write-segments:loop/disp8
+1044 $write-segments:break:
+1045     # flush(out)
+1046     # . . push args
+1047     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
+1048     # . . call
+1049     e8/call  flush/disp32
+1050     # . . discard args
+1051     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+1052 $write-segments:end:
+1053     # . restore registers
+1054     5e/pop-to-esi
+1055     5a/pop-to-edx
+1056     58/pop-to-eax
+1057     # . epilogue
+1058     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+1059     5d/pop-to-ebp
+1060     c3/return
+1061 
+1062 # . . vim:nowrap:textwidth=0
+
+ + + -- cgit 1.4.1-2-gfad0