diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2021-08-22 21:06:36 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2021-08-22 21:09:28 -0700 |
commit | 827dd4a7fe98e80e776b206bb4966e22e22ce3c9 (patch) | |
tree | 699e33beb349cee09fc82d81dfd9c7ebef25e90a | |
parent | b41aed4a9adda23ca2613a24fefa3eafbd611987 (diff) | |
download | mu-827dd4a7fe98e80e776b206bb4966e22e22ce3c9.tar.gz |
start throwing error on duplicate label
One less error that's only in the bootstrap phase. On the other hand, for simplicity I got rid of the ability to override the Entry label. One less special case, but we're also going further from the ability to run subsets of layers. We haven't really been exercising it for a long time, though (commit 7842, March 2021 when we made baremetal the default).
-rw-r--r-- | linux/101_write.subx | 6 | ||||
-rw-r--r-- | linux/102test.subx | 26 | ||||
-rw-r--r-- | linux/103kernel-string-equal.subx | 10 | ||||
-rw-r--r-- | linux/104new-segment.subx | 40 | ||||
-rw-r--r-- | linux/105string-equal.subx | 12 | ||||
-rw-r--r-- | linux/120allocate.subx | 24 | ||||
-rw-r--r-- | linux/131table.subx | 311 | ||||
-rwxr-xr-x | linux/assort | bin | 46801 -> 47302 bytes | |||
-rwxr-xr-x | linux/braces | bin | 48854 -> 49355 bytes | |||
-rwxr-xr-x | linux/calls | bin | 53837 -> 54338 bytes | |||
-rwxr-xr-x | linux/dquotes | bin | 50423 -> 50924 bytes | |||
-rwxr-xr-x | linux/hex | bin | 48981 -> 49482 bytes | |||
-rwxr-xr-x | linux/labels_baremetal | bin | 51541 -> 52042 bytes | |||
-rw-r--r-- | linux/labels_baremetal.subx | 8 | ||||
-rwxr-xr-x | linux/mu | bin | 608888 -> 609389 bytes | |||
-rwxr-xr-x | linux/pack | bin | 59811 -> 60312 bytes | |||
-rwxr-xr-x | linux/sigils | bin | 61208 -> 61709 bytes | |||
-rwxr-xr-x | linux/survey_baremetal | bin | 47482 -> 47983 bytes | |||
-rw-r--r-- | linux/survey_baremetal.subx | 6 | ||||
-rwxr-xr-x | linux/survey_elf | bin | 56375 -> 56876 bytes | |||
-rw-r--r-- | linux/survey_elf.subx | 8 | ||||
-rwxr-xr-x | linux/test_apps | 6 | ||||
-rwxr-xr-x | linux/tests | bin | 45592 -> 46093 bytes | |||
-rw-r--r-- | subx.md | 4 |
24 files changed, 385 insertions, 76 deletions
diff --git a/linux/101_write.subx b/linux/101_write.subx index e1d64756..84718265 100644 --- a/linux/101_write.subx +++ b/linux/101_write.subx @@ -5,9 +5,9 @@ # . op subop mod rm32 base index scale r32 # . 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 -Entry: # just exit; can't test _write just yet - bb/copy-to-ebx 0/imm32 - e8/call syscall_exit/disp32 +#? Entry: # just exit; can't test _write just yet +#? bb/copy-to-ebx 0/imm32 +#? e8/call syscall_exit/disp32 _write: # fd: int, s: (addr array byte) # . prologue diff --git a/linux/102test.subx b/linux/102test.subx index 90207e29..51ca2e12 100644 --- a/linux/102test.subx +++ b/linux/102test.subx @@ -5,19 +5,19 @@ # . op subop mod rm32 base index scale r32 # . 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 -Entry: # manual test - # check-ints-equal(34, 34) - # . . push args - 68/push "error in check-ints-equal"/imm32 - 68/push 34/imm32 - 68/push 34/imm32 - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # syscall_exit(0) - bb/copy-to-ebx 0/imm32 - e8/call syscall_exit/disp32 +#? Entry: # manual test +#? # check-ints-equal(34, 34) +#? # . . push args +#? 68/push "error in check-ints-equal"/imm32 +#? 68/push 34/imm32 +#? 68/push 34/imm32 +#? # . . call +#? e8/call check-ints-equal/disp32 +#? # . . discard args +#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +#? # syscall_exit(0) +#? bb/copy-to-ebx 0/imm32 +#? e8/call syscall_exit/disp32 # print msg to stderr if a != b, otherwise print "." check-ints-equal: # a: int, b: int, msg: (addr array byte) diff --git a/linux/103kernel-string-equal.subx b/linux/103kernel-string-equal.subx index 29dbb6e2..a5da1747 100644 --- a/linux/103kernel-string-equal.subx +++ b/linux/103kernel-string-equal.subx @@ -22,11 +22,11 @@ # . op subop mod rm32 base index scale r32 # . 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 -Entry: # run all tests - e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. - # syscall_exit(Num-test-failures) - 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32 # copy *Num-test-failures to ebx - e8/call syscall_exit/disp32 +#? Entry: # run all tests +#? e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. +#? # syscall_exit(Num-test-failures) +#? 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32 # copy *Num-test-failures to ebx +#? e8/call syscall_exit/disp32 kernel-string-equal?: # s: (addr kernel-string), benchmark: (addr array byte) -> result/eax: boolean # pseudocode: diff --git a/linux/104new-segment.subx b/linux/104new-segment.subx index 723e1afb..5a79ff19 100644 --- a/linux/104new-segment.subx +++ b/linux/104new-segment.subx @@ -16,26 +16,26 @@ # . op subop mod rm32 base index scale r32 # . 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 -Entry: # manual test - # var ad/ecx: allocation-descriptor - 68/push 0/imm32/limit - 68/push 0/imm32/curr - 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # new-segment(0x1000, ad) - # . . push args - 51/push-ecx - 68/push 0x1000/imm32 - # . . call - e8/call new-segment/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # var eax: (addr _) = ad->curr - 8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax - # write to *eax to check that we have access to the newly-allocated segment - c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0x34/imm32 # copy to *eax - # syscall_exit(eax) - 89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx - e8/call syscall_exit/disp32 +#? Entry: # manual test +#? # var ad/ecx: allocation-descriptor +#? 68/push 0/imm32/limit +#? 68/push 0/imm32/curr +#? 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +#? # new-segment(0x1000, ad) +#? # . . push args +#? 51/push-ecx +#? 68/push 0x1000/imm32 +#? # . . call +#? e8/call new-segment/disp32 +#? # . . discard args +#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +#? # var eax: (addr _) = ad->curr +#? 8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax +#? # write to *eax to check that we have access to the newly-allocated segment +#? c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0x34/imm32 # copy to *eax +#? # syscall_exit(eax) +#? 89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx +#? e8/call syscall_exit/disp32 new-segment: # len: int, ad: (addr allocation-descriptor) # . prologue diff --git a/linux/105string-equal.subx b/linux/105string-equal.subx index ae753855..38e88f76 100644 --- a/linux/105string-equal.subx +++ b/linux/105string-equal.subx @@ -5,12 +5,12 @@ # . op subop mod rm32 base index scale r32 # . 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 -Entry: # run all tests -#? e8/call test-compare-equal-strings/disp32 - e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. - # syscall_exit(Num-test-failures) - 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32 # copy *Num-test-failures to ebx - e8/call syscall_exit/disp32 +#? Entry: # run all tests +#? #? e8/call test-compare-equal-strings/disp32 +#? e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. +#? # syscall_exit(Num-test-failures) +#? 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32 # copy *Num-test-failures to ebx +#? e8/call syscall_exit/disp32 string-equal?: # s: (addr array byte), benchmark: (addr array byte) -> result/eax: boolean # pseudocode: diff --git a/linux/120allocate.subx b/linux/120allocate.subx index 254c5f33..58c6c26d 100644 --- a/linux/120allocate.subx +++ b/linux/120allocate.subx @@ -42,18 +42,18 @@ Next-alloc-id: # int # . op subop mod rm32 base index scale r32 # . 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 -# Let's start initializing the default allocation descriptor. - -Entry: - # initialize heap - # . Heap = new-segment(Heap-size) - # . . push args - 68/push Heap/imm32 - ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Heap-size/disp32 # push *Heap-size - # . . call - e8/call new-segment/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +#? # Let's start initializing the default allocation descriptor. +#? +#? Entry: +#? # initialize heap +#? # . Heap = new-segment(Heap-size) +#? # . . push args +#? 68/push Heap/imm32 +#? ff 6/subop/push 0/mod/indirect 5/rm32/.disp32 . . . Heap-size/disp32 # push *Heap-size +#? # . . call +#? e8/call new-segment/disp32 +#? # . . discard args +#? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. $array-equal-main:end: diff --git a/linux/131table.subx b/linux/131table.subx index aa47204b..4df7a7a9 100644 --- a/linux/131table.subx +++ b/linux/131table.subx @@ -700,6 +700,154 @@ $test-get-or-insert:end: 5d/pop-to-ebp c3/return +# save 'key' to the next available row +# if key already exists, abort +# if there are no rows free, abort +# return the address of the value +insert-or-abort: # table: (addr stream {(handle array byte), T}), key: (addr array byte), row-size: int, ad: (addr allocation-descriptor) -> result/eax: (addr T) + # pseudocode: + # curr = table->data + # max = &table->data[table->write] + # while curr < max + # var c: (addr array byte) = lookup(*curr) + # if string-equal?(key, c) + # abort + # curr += row-size + # if table->write >= table->size + # abort + # zero-out(max, row-size) + # copy-array(ad, key, max) + # table->write += row-size + # return max+8 + # + # . 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 + 56/push-esi + # esi = table + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi + # var curr/ecx: (addr handle array byte) = table->data + 8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx + # var max/edx: (addr byte) = &table->data[table->write] + 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx + 8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx +$insert-or-abort:search-loop: + # if (curr >= max) break + 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx + 73/jump-if-addr>= $insert-or-abort:not-found/disp8 + # var c/eax: (addr array byte) = lookup(*curr) + # . . push args + ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) + ff 6/subop/push 0/mod/indirect 1/rm32/ecx . . . . . . # push *ecx + # . . call + e8/call lookup/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # if (string-equal?(key, c)) abort + # . eax = string-equal?(key, c) + # . . push args + 50/push-eax + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + # . . call + e8/call string-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . if (eax != false) abort + 3d/compare-eax-and 0/imm32/false + 0f 85/jump-if-!= $insert-or-abort:error-duplicate/disp32 + # curr += row-size + 03/add 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0x10/disp8 . # add *(ebp+16) to ecx + # loop + eb/jump $insert-or-abort:search-loop/disp8 +$insert-or-abort:not-found: + # if (table->write >= table->size) abort + 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx + 3b/compare 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 8/disp8 . # compare ecx with *(esi+8) + 0f 83/jump-if-addr>= $insert-or-abort:error-full/disp32 + # zero-out(max, row-size) + # . . push args + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) + 52/push-edx + # . . call + e8/call zero-out/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # copy-array(ad, key, max) + # . . push args + 52/push-edx + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x14/disp8 . # push *(ebp+20) + # . . call + e8/call copy-array/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + # table->write += row-size + # . eax = row-size + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax + # . table->write += eax + 01/add 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # add eax to *esi + # return max+8 + # . eax = max + 89/copy 3/mod/direct 0/rm32/eax . . . 2/r32/edx . . # copy edx to eax + # . eax += 8 + 05/add-to-eax 8/imm32 +$insert-or-abort:end: + # . restore registers + 5e/pop-to-esi + 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 + +$insert-or-abort:error-duplicate: + # . _write(2/stderr, error) + # . . push args + 68/push "insert-or-abort: key already exists: "/imm32 + 68/push 2/imm32/stderr + # . . call + e8/call _write/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . _write(2/stderr, key) + # . . push args + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 68/push 2/imm32/stderr + # . . call + e8/call _write/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . _write(2/stderr, "\n") + # . . push args + 68/push "\n"/imm32 + 68/push 2/imm32/stderr + # . . call + e8/call _write/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . syscall_exit(1) + bb/copy-to-ebx 1/imm32 + e8/call syscall_exit/disp32 + # never gets here + +$insert-or-abort:error-full: + # . _write(2/stderr, error) + # . . push args + 68/push "insert-or-abort: table is full\n"/imm32 + 68/push 2/imm32/stderr + # . . call + e8/call _write/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . syscall_exit(1) + bb/copy-to-ebx 1/imm32 + e8/call syscall_exit/disp32 + # never gets here + # if no row is found, save 'key' to the next available row # if there are no rows free, abort # return the address of the value @@ -1321,6 +1469,169 @@ $test-get-or-insert-slice:end: 5d/pop-to-ebp c3/return +# if no row is found, save 'key' in the next available row +# if there are no rows free, abort +insert-slice-or-abort: # table: (addr stream {(handle array byte), T}), key: (addr slice), row-size: int, ad: (addr allocation-descriptor) -> result/eax: (addr T) + # pseudocode: + # curr = table->data + # max = &table->data[table->write] + # while curr < max + # var c: (addr array byte) = lookup(*curr) + # if slice-equal?(key, *curr) + # return curr+8 + # curr += row-size + # if table->write >= table->size + # abort + # zero-out(max, row-size) + # slice-to-string(ad, key, max) + # table->write += row-size + # return max+8 + # + # . 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 + 56/push-esi + # esi = table + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi + # var curr/ecx: (addr handle array byte) = table->data + 8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx + # var max/edx: (addr byte) = &table->data[table->write] + 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx + 8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx +$insert-slice-or-abort:search-loop: + # if (curr >= max) break + 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx + 73/jump-if-addr>= $insert-slice-or-abort:not-found/disp8 + # var c/eax: (addr array byte) = lookup(*curr) + # . . push args + ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) + ff 6/subop/push 0/mod/indirect 1/rm32/ecx . . . . . . # push *ecx + # . . call + e8/call lookup/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # if (slice-equal?(key, c)) abort + # . eax = slice-equal?(key, c) + # . . push args + 50/push-eax + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + # . . call + e8/call slice-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . if (eax != false) abort + 3d/compare-eax-and 0/imm32/false + 0f 85/jump-if-!= $insert-slice-or-abort:error-duplicate/disp32 + # curr += row-size + 03/add 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0x10/disp8 . # add *(ebp+16) to ecx + # loop + eb/jump $insert-slice-or-abort:search-loop/disp8 +$insert-slice-or-abort:not-found: + # result/eax = 0 + 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax + # if (table->write >= table->size) abort + 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx + 3b/compare 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 8/disp8 . # compare ecx with *(esi+8) + 0f 8d/jump-if->= $insert-slice-or-abort:error-full/disp32 + # zero-out(max, row-size) + # . . push args + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) + 52/push-edx + # . . call + e8/call zero-out/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # slice-to-string(ad, key, max) + # . . push args + 52/push-edx + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x14/disp8 . # push *(ebp+20) + # . . call + e8/call slice-to-string/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + # table->write += row-size + # . eax = row-size + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax + # . table->write += eax + 01/add 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # add eax to *esi + # return max+8 + # . eax = max + 89/copy 3/mod/direct 0/rm32/eax . . . 2/r32/edx . . # copy edx to eax + # . eax += 8 + 05/add-to-eax 8/imm32 +$insert-slice-or-abort:end: + # . restore registers + 5e/pop-to-esi + 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 + +$insert-slice-or-abort:error-duplicate: + # . flush(Stderr) + # . . push args + 68/push Stderr/imm32 + # . . call + e8/call flush/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + # . _write(2/stderr, error) + # . . push args + 68/push "insert-slice-or-abort: key already exists: "/imm32 + 68/push 2/imm32/stderr + # . . call + e8/call _write/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . write-slice-buffered(Stderr, key) + # . . push args + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 68/push Stderr/imm32 + # . . call + e8/call write-slice-buffered/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . flush(Stderr) + # . . push args + 68/push Stderr/imm32 + # . . call + e8/call flush/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + # . _write(2/stderr, "\n") + # . . push args + 68/push "\n"/imm32 + 68/push 2/imm32/stderr + # . . call + e8/call _write/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . syscall_exit(1) + bb/copy-to-ebx 1/imm32 + e8/call syscall_exit/disp32 + # never gets here + +$insert-slice-or-abort:error-full: + # . _write(2/stderr, error) + # . . push args + 68/push "insert-slice-or-abort: table is full\n"/imm32 + 68/push 2/imm32/stderr + # . . call + e8/call _write/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . syscall_exit(1) + bb/copy-to-ebx 1/imm32 + e8/call syscall_exit/disp32 + # never gets here + + # if no row is found, stop(ed) get-or-stop: # table: (addr stream {(handle array byte), T}), key: (addr array byte), row-size: int, # abort-message-prefix: (addr array byte), err: (addr buffered-file), ed: (addr exit-descriptor) diff --git a/linux/assort b/linux/assort index f4f73847..960b45df 100755 --- a/linux/assort +++ b/linux/assort Binary files differdiff --git a/linux/braces b/linux/braces index 0930284c..bb79fe27 100755 --- a/linux/braces +++ b/linux/braces Binary files differdiff --git a/linux/calls b/linux/calls index e2c8b5bb..a4b5c875 100755 --- a/linux/calls +++ b/linux/calls Binary files differdiff --git a/linux/dquotes b/linux/dquotes index 0339ae16..e43323f3 100755 --- a/linux/dquotes +++ b/linux/dquotes Binary files differdiff --git a/linux/hex b/linux/hex index e6c63c83..e242824f 100755 --- a/linux/hex +++ b/linux/hex Binary files differdiff --git a/linux/labels_baremetal b/linux/labels_baremetal index 12a545ca..66fcbd97 100755 --- a/linux/labels_baremetal +++ b/linux/labels_baremetal Binary files differdiff --git a/linux/labels_baremetal.subx b/linux/labels_baremetal.subx index e1743c0b..6e1d559b 100644 --- a/linux/labels_baremetal.subx +++ b/linux/labels_baremetal.subx @@ -216,7 +216,7 @@ load-labels: # in: (addr buffered-file), labels: (stream {label-name, address} # read-line-buffered(in, line) # if (line->write == 0) break # end of file # var word-slice/ecx: (addr slice) = next-word(line) - # var dest/edi: (addr int) = get-or-insert-slice(labels, word-slice, 12 bytes/row) + # var dest/edi: (addr int) = insert-slice-or-abort(labels, word-slice, 12 bytes/row) # word-slice = next-word(line) # var address/eax: int = parse-hex-int-from-slice(word-slice) # *dest = address @@ -333,15 +333,15 @@ $load-labels:loop: #? # . . discard args #? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp #? # }}} - # var dest/edi: (addr int) = get-or-insert-slice(labels, word-slice, 12 bytes/row, Heap) - # . eax = get-or-insert-slice(labels, word-slice, 12 bytes/row, Heap) + # var dest/edi: (addr int) = insert-slice-or-abort(labels, word-slice, 12 bytes/row, Heap) + # . eax = insert-slice-or-abort(labels, word-slice, 12 bytes/row, Heap) # . . push args 68/push Heap/imm32 68/push 0xc/imm32/row-size 52/push-edx ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) # . . call - e8/call get-or-insert-slice/disp32 + e8/call insert-slice-or-abort/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp # . edi = eax diff --git a/linux/mu b/linux/mu index ecf884a2..ff127f40 100755 --- a/linux/mu +++ b/linux/mu Binary files differdiff --git a/linux/pack b/linux/pack index 32db6ad3..659fafe7 100755 --- a/linux/pack +++ b/linux/pack Binary files differdiff --git a/linux/sigils b/linux/sigils index 3bcd2d9c..f390b17e 100755 --- a/linux/sigils +++ b/linux/sigils Binary files differdiff --git a/linux/survey_baremetal b/linux/survey_baremetal index b5429495..d794d9b0 100755 --- a/linux/survey_baremetal +++ b/linux/survey_baremetal Binary files differdiff --git a/linux/survey_baremetal.subx b/linux/survey_baremetal.subx index 40115cd8..e7d12b7c 100644 --- a/linux/survey_baremetal.subx +++ b/linux/survey_baremetal.subx @@ -468,6 +468,8 @@ compute-addresses: # in: (addr stream byte), labels: (addr stream {(handle arra # current-address = new-address # else if label?(word-slice) # strip trailing ':' from word-slice + # var tmp/eax: (addr int) = insert-slice-or-abort(labels, word-slice) + # *tmp = current-address # trace("label '" word-slice "' is at address " current-address ".") # # labels occupy no space, so no need to increment offsets # else @@ -661,14 +663,14 @@ $compute-addresses:case-label: 0f 84/jump-if-= $compute-addresses:case-default/disp32 # strip trailing ':' from word-slice ff 1/subop/decrement 1/mod/*+disp8 2/rm32/edx . . . . 4/disp8 . # decrement *(edx+4) - # var tmp/eax: (addr int) = get-or-insert-slice(labels, word-slice, row-size=12) + # var tmp/eax: (addr int) = insert-slice-or-abort(labels, word-slice, row-size=12) # . . push args 68/push Heap/imm32 68/push 0xc/imm32/row-size 52/push-edx ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) # . . call - e8/call get-or-insert-slice/disp32 + e8/call insert-slice-or-abort/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp # *tmp = current-address diff --git a/linux/survey_elf b/linux/survey_elf index 9d1a715c..c5f59cca 100755 --- a/linux/survey_elf +++ b/linux/survey_elf Binary files differdiff --git a/linux/survey_elf.subx b/linux/survey_elf.subx index 838feb88..59fb5af4 100644 --- a/linux/survey_elf.subx +++ b/linux/survey_elf.subx @@ -451,7 +451,7 @@ compute-offsets: # in: (addr stream byte), segments: (addr stream {(handle arra # break (next line) # else if label?(word-slice) # strip trailing ':' from word-slice - # linfo: (addr label-info) = get-or-insert-slice(labels, word-slice) + # linfo: (addr label-info) = insert-slice-or-abort(labels, word-slice) # linfo->segment-name = curr-segment-name # trace("label '", word-slice, "' is in segment '", curr-segment-name, "'.") # linfo->segment-offset = segment-offset @@ -753,15 +753,15 @@ $compute-offsets:case-label: 0f 84/jump-if-= $compute-offsets:case-default/disp32 # strip trailing ':' from word-slice ff 1/subop/decrement 1/mod/*+disp8 2/rm32/edx . . . . 4/disp8 . # decrement *(edx+4) - # linfo/edi = get-or-insert-slice(labels, word-slice, row-size=24) - # . eax = get-or-insert-slice(labels, word-slice, row-size=24) + # linfo/edi = insert-slice-or-abort(labels, word-slice, row-size=24) + # . eax = insert-slice-or-abort(labels, word-slice, row-size=24) # . . push args 68/push Heap/imm32 68/push 0x18/imm32/row-size 52/push-edx ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) # . . call - e8/call get-or-insert-slice/disp32 + e8/call insert-slice-or-abort/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp # . edi = eax diff --git a/linux/test_apps b/linux/test_apps index 9dab3e41..a72b1ce5 100755 --- a/linux/test_apps +++ b/linux/test_apps @@ -227,7 +227,7 @@ test "$1" = 'record' || git diff --exit-code sigils } echo calls -cat [012]*.subx subx-params.subx calls.subx | sigils > a.sigils +cat [012]*.subx subx-params.subx calls.subx | ./sigils > a.sigils bootstrap/bootstrap translate a.sigils -o calls test "$1" = 'record' || git diff --exit-code calls { @@ -241,7 +241,7 @@ test "$1" = 'record' || git diff --exit-code calls } echo braces -cat [012]*.subx subx-params.subx braces.subx | calls | sigils > a.sigils +cat [012]*.subx subx-params.subx braces.subx | ./calls | ./sigils > a.sigils bootstrap/bootstrap translate a.sigils -o braces test "$1" = 'record' || git diff --exit-code braces { @@ -255,7 +255,7 @@ test "$1" = 'record' || git diff --exit-code braces } echo mu -cat [0-2]*.subx mu.subx | braces | calls | sigils > a.sigils +cat [0-2]*.subx mu.subx | ./braces | ./calls | ./sigils > a.sigils bootstrap/bootstrap translate a.sigils -o mu test "$1" = 'record' || git diff --exit-code mu { diff --git a/linux/tests b/linux/tests index 04a112ef..e9b31bb9 100755 --- a/linux/tests +++ b/linux/tests Binary files differdiff --git a/subx.md b/subx.md index d2b9ad50..1d281ced 100644 --- a/subx.md +++ b/subx.md @@ -138,10 +138,6 @@ Functions are called using the following syntax: Function arguments must be either literals (integers or strings) or a reg/mem operand using the syntax in the previous section. -A special label on Linux is `Entry`, which can be used to specify/override the -entry point of the program. It doesn't have to be unique, and the latest -definition will override earlier ones. - Another special pair of labels are the block delimiters `{` and `}`. They can be nested, and jump instructions can take arguments `loop` or `break` that jump to the enclosing `{` and `}` respectively. |