diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-03-15 21:03:12 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-03-15 21:03:12 -0700 |
commit | c48ce3c8bfb6d1578f2530ed84b8e7b25d435b6d (patch) | |
tree | 9a7b23b95d9960853aad1be4e6e95b12f300ade8 | |
parent | f559236bdf9103c5f88d8dfc098f3afe3de64e4a (diff) | |
download | mu-c48ce3c8bfb6d1578f2530ed84b8e7b25d435b6d.tar.gz |
6153 - switch 'main' to use Mu strings
At the SubX level we have to put up with null-terminated kernel strings for commandline args. But so far we haven't done much with them. Rather than try to support them we'll just convert them transparently to standard length-prefixed strings. In the process I realized that it's not quite right to treat the combination of argc and argv as an array of kernel strings. Argc counts the number of elements, whereas the length of an array is usually denominated in bytes.
-rw-r--r-- | 069allocate.subx | 32 | ||||
-rw-r--r-- | 102kernel-string.subx | 89 | ||||
-rwxr-xr-x | apps/assort | bin | 40852 -> 40886 bytes | |||
-rwxr-xr-x | apps/braces | bin | 42658 -> 42692 bytes | |||
-rwxr-xr-x | apps/calls | bin | 47319 -> 47353 bytes | |||
-rwxr-xr-x | apps/crenshaw2-1 | bin | 40260 -> 40294 bytes | |||
-rwxr-xr-x | apps/crenshaw2-1b | bin | 40807 -> 40841 bytes | |||
-rwxr-xr-x | apps/dquotes | bin | 44502 -> 44536 bytes | |||
-rwxr-xr-x | apps/factorial | bin | 39279 -> 39313 bytes | |||
-rw-r--r-- | apps/factorial.mu | 14 | ||||
-rwxr-xr-x | apps/handle | bin | 40177 -> 40211 bytes | |||
-rwxr-xr-x | apps/hex | bin | 43099 -> 43133 bytes | |||
-rwxr-xr-x | apps/mu | bin | 210747 -> 210914 bytes | |||
-rwxr-xr-x | apps/pack | bin | 53244 -> 53278 bytes | |||
-rwxr-xr-x | apps/sigils | bin | 55043 -> 55077 bytes | |||
-rwxr-xr-x | apps/survey | bin | 50093 -> 50127 bytes | |||
-rwxr-xr-x | apps/tests | bin | 39650 -> 39684 bytes | |||
-rw-r--r-- | mu-init-test.subx | 8 | ||||
-rw-r--r-- | mu-init.subx | 45 |
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) |