diff options
-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. |