about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--069allocate.subx32
-rw-r--r--102kernel-string.subx89
-rwxr-xr-xapps/assortbin40852 -> 40886 bytes
-rwxr-xr-xapps/bracesbin42658 -> 42692 bytes
-rwxr-xr-xapps/callsbin47319 -> 47353 bytes
-rwxr-xr-xapps/crenshaw2-1bin40260 -> 40294 bytes
-rwxr-xr-xapps/crenshaw2-1bbin40807 -> 40841 bytes
-rwxr-xr-xapps/dquotesbin44502 -> 44536 bytes
-rwxr-xr-xapps/factorialbin39279 -> 39313 bytes
-rw-r--r--apps/factorial.mu14
-rwxr-xr-xapps/handlebin40177 -> 40211 bytes
-rwxr-xr-xapps/hexbin43099 -> 43133 bytes
-rwxr-xr-xapps/mubin210747 -> 210914 bytes
-rwxr-xr-xapps/packbin53244 -> 53278 bytes
-rwxr-xr-xapps/sigilsbin55043 -> 55077 bytes
-rwxr-xr-xapps/surveybin50093 -> 50127 bytes
-rwxr-xr-xapps/testsbin39650 -> 39684 bytes
-rw-r--r--mu-init-test.subx8
-rw-r--r--mu-init.subx45
19 files changed, 170 insertions, 18 deletions
diff --git a/069allocate.subx b/069allocate.subx
index 48ba9413..503d151f 100644
--- a/069allocate.subx
+++ b/069allocate.subx
@@ -234,4 +234,36 @@ $allocate-region:abort:
     cd/syscall  0x80/imm8
     # never gets here
 
+# Claim the next 'n+4' bytes of memory and initialize the first 4 to n.
+# Abort if there isn't enough memory in 'ad'.
+allocate-array:  # ad: (addr allocation-descriptor), n: int -> result/eax: (addr _)
+    # . prologue
+    55/push-ebp
+    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+    # . save registers
+    51/push-ecx
+    52/push-edx
+    # ecx = n
+    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   0xc/disp8       .                 # copy *(ebp+0xc) to ecx
+    # var size/edx: int = n+4
+    8d/copy-address                 1/mod/*+disp8   1/rm32/ecx    .           .             .           2/r32/edx   4/disp8         .                 # copy ecx+4 to edx
+    # result = allocate(ad, size)
+    # . . push args
+    52/push-edx
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
+    # . . call
+    e8/call  allocate/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+    # *result = n
+    89/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy ecx to *eax
+$allocate-array:end:
+    # . restore registers
+    5a/pop-to-edx
+    59/pop-to-ecx
+    # . epilogue
+    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+    5d/pop-to-ebp
+    c3/return
+
 # . . vim:nowrap:textwidth=0
diff --git a/102kernel-string.subx b/102kernel-string.subx
new file mode 100644
index 00000000..ca92d813
--- /dev/null
+++ b/102kernel-string.subx
@@ -0,0 +1,89 @@
+# We can't really do much with null-terminated kernel strings, and we don't
+# want to. Let's turn them into regular length-prefixed strings at the first
+# opportunity.
+
+== code
+
+kernel-string-to-string:  # ad: (addr allocation-descriptor), in: (addr kernel-string) -> result/eax: (addr array byte)
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
+    51/push-ecx
+    52/push-edx
+    53/push-ebx
+    56/push-esi
+    57/push-edi
+    # var len/ecx: int = length(in)
+    (kernel-string-length *(ebp+0xc))
+    89/<- %ecx 0/r32/eax
+    # result = allocate-array(ad, len)
+    (allocate-array *(ebp+8) %ecx)  # => eax
+    # var c/edx: byte = 0
+    ba/copy-to-edx 0/imm32
+    # var src/esi: (addr byte) = in
+    8b/-> *(ebp+0xc) 6/r32/esi
+    # var dest/edi: (addr byte) = result->data
+    8d/copy-address *(eax+4) 7/r32/edi
+    {
+$kernel-string-to-string:loop:
+      # c = *src
+      8a/byte-> *esi 2/r32/edx
+      # if (c == 0) break
+      81 7/subop/compare %edx 0/imm32
+      74/jump-if-= break/disp8
+      # *dest = c
+      88/byte<- *edi 2/r32/edx
+      # ++src
+      46/increment-esi
+      # ++dest
+      47/increment-edi
+      eb/jump loop/disp8
+    }
+$kernel-string-to-string:end:
+    # . restore registers
+    5f/pop-to-edi
+    5e/pop-to-esi
+    5b/pop-to-ebx
+    5a/pop-to-edx
+    59/pop-to-ecx
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
+
+kernel-string-length:  # in: (addr kernel-string) -> result/eax: int
+    # . prologue
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
+    51/push-ecx
+    52/push-edx
+    # result = 0
+    b8/copy-to-eax 0/imm32
+    # var c/ecx: byte = 0
+    b9/copy-to-ecx 0/imm32
+    # var curr/edx: (addr byte) = in
+    8b/-> *(ebp+8) 2/r32/edx
+    {
+$kernel-string-length:loop:
+      # c = *curr
+      8a/byte-> *edx 1/r32/ecx
+      # if (c == 0) break
+      81 7/subop/compare %ecx 0/imm32
+      74/jump-if-= break/disp8
+      # ++curr
+      42/increment-edx
+      # ++result
+      40/increment-eax
+      #
+      eb/jump loop/disp8
+    }
+$kernel-string-length:end:
+    # . restore registers
+    5a/pop-to-edx
+    59/pop-to-ecx
+    # . epilogue
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return
diff --git a/apps/assort b/apps/assort
index 980e294d..0dacda05 100755
--- a/apps/assort
+++ b/apps/assort
Binary files differdiff --git a/apps/braces b/apps/braces
index 0de3adb7..318f8309 100755
--- a/apps/braces
+++ b/apps/braces
Binary files differdiff --git a/apps/calls b/apps/calls
index 4015ed83..1ffc0b94 100755
--- a/apps/calls
+++ b/apps/calls
Binary files differdiff --git a/apps/crenshaw2-1 b/apps/crenshaw2-1
index ce6d02d7..fe3bdfc1 100755
--- a/apps/crenshaw2-1
+++ b/apps/crenshaw2-1
Binary files differdiff --git a/apps/crenshaw2-1b b/apps/crenshaw2-1b
index d429e9c6..30266c2a 100755
--- a/apps/crenshaw2-1b
+++ b/apps/crenshaw2-1b
Binary files differdiff --git a/apps/dquotes b/apps/dquotes
index fd1bae17..5a3d8aa0 100755
--- a/apps/dquotes
+++ b/apps/dquotes
Binary files differdiff --git a/apps/factorial b/apps/factorial
index e21f6dfa..73a3417f 100755
--- a/apps/factorial
+++ b/apps/factorial
Binary files differdiff --git a/apps/factorial.mu b/apps/factorial.mu
index 83b2bedf..55bee98e 100644
--- a/apps/factorial.mu
+++ b/apps/factorial.mu
@@ -31,21 +31,21 @@ fn test-factorial {
   check-ints-equal result 0x78 "F - test-factorial"
 }
 
-fn main args: (addr array kernel-string) -> exit-status/ebx: int {
-  var a/eax: (addr array kernel-string) <- copy args
+fn main args: (addr array string) -> exit-status/ebx: int {
+  var a/eax: (addr array string) <- copy args
   var tmp/ecx: int <- length a
   $main-body: {
-    compare tmp, 1
-    # if (len(args) == 1) factorial(5)
+    # if (len(args) <= 4) factorial(5)
+    compare tmp, 4
     {
-      break-if-!=
+      break-if->
       var tmp/eax: int <- factorial 5
       exit-status <- copy tmp
       break $main-body
     }
     # if (args[1] == "test") run-tests()
-    var tmp2/ecx: (addr kernel-string) <- index a, 1
-    var tmp3/eax: boolean <- kernel-string-equal? *tmp2, "test"
+    var tmp2/ecx: (addr string) <- index a, 1
+    var tmp3/eax: boolean <- string-equal? *tmp2, "test"
     compare tmp3, 0
     {
       break-if-=
diff --git a/apps/handle b/apps/handle
index 76fd78ee..77834947 100755
--- a/apps/handle
+++ b/apps/handle
Binary files differdiff --git a/apps/hex b/apps/hex
index d91286e0..2f14cc9a 100755
--- a/apps/hex
+++ b/apps/hex
Binary files differdiff --git a/apps/mu b/apps/mu
index 17916ee9..4b34fd01 100755
--- a/apps/mu
+++ b/apps/mu
Binary files differdiff --git a/apps/pack b/apps/pack
index ceeeb153..f788a54a 100755
--- a/apps/pack
+++ b/apps/pack
Binary files differdiff --git a/apps/sigils b/apps/sigils
index c738b004..7035952d 100755
--- a/apps/sigils
+++ b/apps/sigils
Binary files differdiff --git a/apps/survey b/apps/survey
index 49905f1a..58589cb5 100755
--- a/apps/survey
+++ b/apps/survey
Binary files differdiff --git a/apps/tests b/apps/tests
index 39c29b36..08005a42 100755
--- a/apps/tests
+++ b/apps/tests
Binary files differdiff --git a/mu-init-test.subx b/mu-init-test.subx
index 6cfe51b2..1b2d1683 100644
--- a/mu-init-test.subx
+++ b/mu-init-test.subx
@@ -1,10 +1,10 @@
 # Just a test stub for mu-init.subx
 #
 # Try it out like this:
-#   $ ./translate_subx init.linux 0*.subx mu-init.subx mu-init-test.subx
+#   $ ./translate_subx init.linux [0-9]*.subx mu-init.subx mu-init-test.subx
 #   $ ./a.elf  # should run all tests
 
-main:  # args: (address array kernel-string) -> result/ebx: int
+main:  # args: (addr array (addr array byte)) -> result/ebx: int
     # . prologue
     55/push-ebp
     89/<- %ebp 4/r32/esp
@@ -15,10 +15,10 @@ main:  # args: (address array kernel-string) -> result/ebx: int
     8b/-> *(ebp+8) 6/r32/esi
     {
       # if (argc <= 1) break
-      81 7/subop/compare *esi 1/imm32
+      81 7/subop/compare *esi 4/imm32
       7e/jump-if-<= break/disp8
       # if (argv[1] != "test") break
-      (kernel-string-equal? *(esi+8) "test")  # => eax
+      (string-equal? *(esi+8) "test")  # => eax
       3d/compare-eax-and 0/imm32
       74/jump-if-= break/disp8
       #
diff --git a/mu-init.subx b/mu-init.subx
index fb15efbf..2377822e 100644
--- a/mu-init.subx
+++ b/mu-init.subx
@@ -3,7 +3,7 @@
 # See translate_mu for how this file is used.
 #
 # Mu programs start at a function called 'main' with this signature:
-#   fn main args: (addr array kernel-string) -> exit-status/ebx: int
+#   fn main args: (addr array (addr array byte)) -> exit-status/ebx: int
 # If your program doesn't need commandline arguments you can drop it:
 #   fn main -> exit-status/ebx: int
 #
@@ -15,11 +15,42 @@
 Entry:
     # we don't use ebp in Entry; just initialize it
     bd/copy-to-ebp 0/imm32
-    # var args/eax: (addr array kernel-string)
-    89/<- %eax 4/r32/esp
-    # initialize the heap
+    # - save argc and argv
+    # var argc-and-argv/esi
+    89/<- %esi 4/r32/esp
+$Entry:initialize-heap:
+    # - initialize the heap
     (new-segment *Heap-size Heap)
-    # run Mu program
-    (main %eax)
-    # exit
+$Entry:initialize-args:
+    # - convert argv from null-terminated 'kernel' strings to length-prefixed Mu strings
+    # var argc/edx: int
+    8b/-> *esi 2/r32/edx
+    # argc is in words; convert it to bytes
+    c1/shift 4/subop/left %edx 2/imm8
+    # var args/edi: (addr array (addr array byte))
+    (allocate-array Heap %edx)  # => eax
+    89/<- %edi 0/r32/eax
+    # var curr/ecx: (addr kernel-string) = argv
+    8d/copy-address *(esi+4) 1/r32/ecx
+    # var max/edx: (addr kernel-string) = argv+4+argc
+    8d/copy-address *(ecx+edx) 2/r32/edx
+    # var dest/esi: (addr (addr array byte)) = args+4
+    8d/copy-address *(edi+4) 6/r32/esi
+    {
+      # if (curr >= max) break
+      39/compare %ecx 2/r32/edx
+      73/jump-if-addr>= break/disp8
+      # *dest = kernel-string-to-string(*curr)
+      (kernel-string-to-string Heap *ecx)  # => eax
+      89/<- *esi 0/r32/eax
+      # curr += 4
+      81 0/subop/add %ecx 4/imm32
+      # dest += 4
+      81 0/subop/add %esi 4/imm32
+      #
+      eb/jump loop/disp8
+    }
+    # - run Mu program
+    (main %edi)  # => ebx
+    # - exit
     (syscall_exit)