From 18bd3ef902f227735c0be76d8aa293b07d833dd0 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 2 Sep 2019 15:36:08 -0700 Subject: 5607 - start of notation for function calls --- html/apps/calls.subx.html | 279 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 html/apps/calls.subx.html (limited to 'html/apps/calls.subx.html') diff --git a/html/apps/calls.subx.html b/html/apps/calls.subx.html new file mode 100644 index 00000000..e038ab0b --- /dev/null +++ b/html/apps/calls.subx.html @@ -0,0 +1,279 @@ + + + + +Mu - apps/calls.subx + + + + + + + + + + +https://github.com/akkartik/mu/blob/master/apps/calls.subx +
+  1 # Function calls in a single line.
+  2 #
+  3 # To run (on Linux):
+  4 #   $ ./ntranslate 0*.subx apps/subx-common.subx apps/calls.subx
+  5 #   $ mv a.elf apps/calls
+  6 #   $ chmod +x apps/calls
+  7 #
+  8 # Example 1:
+  9 #   $ echo '(foo %eax)'                         |  apps/calls
+ 10 #   # . (foo %eax)                                      # output has comments
+ 11 #   ff 6/subop/push %eax                                # push
+ 12 #   e8/call foo/disp32                                  # call
+ 13 #   81 0/subop/add %esp 4/imm32                         # undo push
+ 14 #
+ 15 # Example 2:
+ 16 #   $ echo '(foo Var1 *(eax + 4) "blah")'       |  apps/calls
+ 17 #   # . (foo Var1 *(eax + 4) "blah")
+ 18 #   68/push "blah"/imm32
+ 19 #   ff 6/subop/push *(eax + 4)                          # push args in..
+ 20 #   68/push Var1/imm32                                  # ..reverse order
+ 21 #   e8/call foo/disp32
+ 22 #   81 0/subop/add %esp 4/imm32                         # undo pushes
+ 23 #
+ 24 # Calls always begin with '(' as the first non-whitespace on a line.
+ 25 
+ 26 == code
+ 27 
+ 28 Entry:  # run tests if necessary, convert stdin if not
+ 29     # . prolog
+ 30     89/<- %ebp 4/r32/esp
+ 31 
+ 32     # initialize heap
+ 33     # . Heap = new-segment(Heap-size)
+ 34     # . . push args
+ 35     68/push Heap/imm32
+ 36     ff 6/subop/push *Heap-size
+ 37     # . . call
+ 38     e8/call new-segment/disp32
+ 39     # . . discard args
+ 40     81 0/subop/add %esp 8/imm32
+ 41 
+ 42     # - if argc > 1 and argv[1] == "test", then return run_tests()
+ 43     # if (argc <= 1) goto run-main
+ 44     81 7/subop/compare *ebp 1/imm32
+ 45     7e/jump-if-lesser-or-equal $run-main/disp8
+ 46     # if (!kernel-string-equal?(argv[1], "test")) goto run-main
+ 47     # . eax = kernel-string-equal?(argv[1], "test")
+ 48     # . . push args
+ 49     68/push "test"/imm32
+ 50     ff 6/subop/push *(ebp+8)
+ 51     # . . call
+ 52     e8/call kernel-string-equal?/disp32
+ 53     # . . discard args
+ 54     81 0/subop/add %esp 8/imm32
+ 55     # . if (eax == 0) goto run-main
+ 56     3d/compare-eax-and 0/imm32
+ 57     74/jump-if-equal $run-main/disp8
+ 58     # run-tests()
+ 59     e8/call run-tests/disp32
+ 60     # syscall(exit, *Num-test-failures)
+ 61     8b/-> *Num-test-failures 3/r32/ebx
+ 62     eb/jump $main:end/disp8
+ 63 $run-main:
+ 64     # - otherwise convert stdin
+ 65     # convert(Stdin, Stdout)
+ 66     # . . push args
+ 67     68/push Stdout/imm32
+ 68     68/push Stdin/imm32
+ 69     # . . call
+ 70     e8/call convert/disp32
+ 71     # . . discard args
+ 72     81 0/subop/add %esp 8/imm32
+ 73     # syscall(exit, 0)
+ 74     bb/copy-to-ebx 0/imm32
+ 75 $main:end:
+ 76     b8/copy-to-eax 1/imm32/exit
+ 77     cd/syscall 0x80/imm8
+ 78 
+ 79 convert:  # in : (address buffered-file), out : (address buffered-file) -> <void>
+ 80     # pseudocode:
+ 81     #   var line = new-stream(512, 1)
+ 82     #   var words : (address stream slice) = new-stream(16, 8)  # at most function name and 15 args
+ 83     #   while true
+ 84     #     clear-stream(line)
+ 85     #     read-line-buffered(in, line)
+ 86     #     if (line->write == 0) break                           # end of file
+ 87     #     skip-chars-matching-whitespace(line)
+ 88     #     if line->data[line->read] != '('
+ 89     #       write-stream-data(out, line)
+ 90     #       continue
+ 91     #     # emit comment
+ 92     #     write-buffered(out, "# ")
+ 93     #     write-stream-data(out, line)
+ 94     #     # emit code
+ 95     #     ++line->read  # skip '('
+ 96     #     clear-stream(words)
+ 97     #     words = parse-line(line)
+ 98     #     emit-call(out, words)
+ 99     #   flush(out)
+100     #
+101     # . prolog
+102     55/push-ebp
+103     89/<- %ebp 4/r32/esp
+104     # . save registers
+105     # var line/ecx : (address stream byte) = stream(512)
+106     81 5/subop/subtract %esp 0x200/imm32
+107     68/push 0x200/imm32/length
+108     68/push 0/imm32/read
+109     68/push 0/imm32/write
+110     89/<- %ecx 4/r32/esp
+111     # var words/edx : (address stream slice) = stream(16, 8)
+112     81 5/subop/subtract %esp 0x80/imm32
+113     68/push 0x80/imm32/length
+114     68/push 0/imm32/read
+115     68/push 0/imm32/write
+116     89/<- %edx 4/r32/esp
+117 $convert:loop:
+118     # clear-stream(line)
+119     # . . push args
+120     51/push-ecx
+121     # . . call
+122     e8/call clear-stream/disp32
+123     # . . discard args
+124     81 0/subop/add %esp 4/imm32
+125     # read-line-buffered(in, line)
+126     # . . push args
+127     51/push-ecx
+128     ff 6/subop/push *(ebp+8)
+129     # . . call
+130     e8/call read-line-buffered/disp32
+131     # . . discard args
+132     81 0/subop/add %esp 8/imm32
+133 $convert:check0:
+134     # if (line->write == 0) break
+135     81 7/subop/compare *ecx 0/imm32
+136     0f 84/jump-if-equal $convert:break/disp32
+137     # TODO
+138     e9/jump $convert:loop/disp32
+139 $convert:break:
+140     # flush(out)
+141     # . . push args
+142     ff 6/subop/push *(ebp+0xc)
+143     # . . call
+144     e8/call  flush/disp32
+145     # . . discard args
+146     81 0/subop/add %esp 4/imm32
+147 $convert:end:
+148     # . reclaim locals
+149     81 0/subop/add %esp 0x298/imm32  # 0x20c + 0x8c
+150     # . restore registers
+151     # . epilog
+152     89/<- %esp 5/r32/ebp
+153     5d/pop-to-ebp
+154     c3/return
+155 
+156 parse-line:  # line : (address stream byte), words : (address stream slice)
+157     # pseudocode:
+158     #   var word-slice : (address slice)
+159     #   while true
+160     #     word-slice = next-word-string-or-expression-without-metadata(line)
+161     #     if slice-empty?(word-slice)
+162     #       break                                 # end of line
+163     #     write-int(words, word-slice->start)
+164     #     write-int(words, word-slice->end)
+165     #
+166     # . prolog
+167     55/push-ebp
+168     89/<- %ebp 4/r32/esp
+169     # . save registers
+170 $parse-line:end:
+171     # . reclaim locals
+172     # . restore registers
+173     # . epilog
+174     89/<- %esp 5/r32/ebp
+175     5d/pop-to-ebp
+176     c3/return
+177 
+178 emit-call:  # out : (address buffered-file), words : (address stream slice)
+179     # pseudocode:
+180     #   if (words->write < 8) abort
+181     #   curr = &words->data[words->write-8]
+182     #   min = words->data
+183     #   # emit pushes
+184     #   while true
+185     #     if (curr <= min) break
+186     #     if (*curr == '%' || *curr == '*')
+187     #       write-buffered(out, "ff 6/subop/push ")
+188     #       write-slice-buffered(out, curr)
+189     #       write-buffered(out, "/imm32\n")
+190     #     else
+191     #       write-buffered(out, "68/push ")
+192     #       write-slice-buffered(out, curr)
+193     #       write-buffered(out, "/imm32\n")
+194     #     curr -= 8
+195     #   # emit call
+196     #   write-buffered(out, "e8/call ")
+197     #   write-slice-buffered(out, curr)
+198     #   write-buffered(out, "/disp32\n")
+199     #   # emit pops
+200     #   write-buffered(out, "81 0/subop/add %esp ")
+201     #   print-int32-buffered(out, words->write >> 1 - 4)
+202     #   write-buffered(out, "/imm32\n")
+203     #
+204     # . prolog
+205     55/push-ebp
+206     89/<- %ebp 4/r32/esp
+207     # . save registers
+208 $emit-call:end:
+209     # . reclaim locals
+210     # . restore registers
+211     # . epilog
+212     89/<- %esp  5/r32/ebp
+213     5d/pop-to-ebp
+214     c3/return
+215 
+216 # . . vim:nowrap:textwidth=0
+
+ + + -- cgit 1.4.1-2-gfad0