From 8188bbbc9408322c18cdc2d1049126900abf793c Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 18 Feb 2019 21:48:19 -0800 Subject: [PATCH] 4981 - no, go back to 3 phases Considering how much trouble a merge phase would be (commit 4978), it seems simpler to just add the extra syntax for controlling the entry point of the generated ELF binary. But I wouldn't have noticed this if I hadn't taken the time to write out the commit messages of 4976 and 4978. Even if we happened to already have linked list primitives built, this may still be a good idea considering that I'm saving quite a lot of code in duplicated entrypoints. --- subx/011run.cc | 16 ++++++------- subx/028translate.cc | 7 +++--- subx/034compute_segment_address.cc | 32 ++++++++++++------------- subx/035labels.cc | 23 +++++++++++++++++- subx/050_write.subx | 4 ++-- subx/051test.subx | 2 +- subx/052kernel-string-equal.subx | 2 +- subx/053new-segment.subx | 2 +- subx/054string-equal.subx | 3 +-- subx/055stream.subx | 7 ------ subx/056trace.subx | 8 ------- subx/057write.subx | 7 ------ subx/058stream-equal.subx | 11 ++++----- subx/059stop.subx | 11 ++++----- subx/060read.subx | 7 ------ subx/061read-byte.subx | 11 ++++----- subx/062write-stream.subx | 14 ++++------- subx/063error.subx | 7 ------ subx/064write-byte.subx | 7 ------ subx/065hex.subx | 7 ------ subx/066print-byte.subx | 7 ------ subx/067write-buffered.subx | 11 ++++----- subx/068error-byte.subx | 13 ++++------- subx/069allocate.subx | 7 ------ subx/070new-stream.subx | 7 ------ subx/071read-line.subx | 7 ------ subx/072slice.subx | 11 ++++----- subx/073next-token.subx | 11 ++++----- subx/Readme.md | 27 +++++++++++----------- subx/apps/crenshaw2-1 | Bin 18370 -> 18028 bytes subx/apps/crenshaw2-1.subx | 3 ++- subx/apps/crenshaw2-1b | Bin 18929 -> 18587 bytes subx/apps/crenshaw2-1b.subx | 3 ++- subx/apps/factorial | Bin 17288 -> 16946 bytes subx/apps/factorial.subx | 7 +++++- subx/apps/handle | Bin 18081 -> 17721 bytes subx/apps/handle.subx | 7 +----- subx/apps/hex | Bin 21349 -> 21007 bytes subx/apps/hex.subx | 5 ++-- subx/apps/merge.subx | 36 ----------------------------- subx/apps/pack | Bin 21526 -> 21184 bytes subx/apps/pack.subx | 5 ++-- subx/examples/ex10.subx | 2 +- subx/examples/ex11.subx | 2 +- subx/examples/ex5.subx | 3 ++- 45 files changed, 129 insertions(+), 233 deletions(-) delete mode 100644 subx/apps/merge.subx diff --git a/subx/011run.cc b/subx/011run.cc index 61d93186..45a6699e 100644 --- a/subx/011run.cc +++ b/subx/011run.cc @@ -15,17 +15,13 @@ put_new(Help, "syntax", "Each segment starts with a header line: a '==' delimiter followed by the name of\n" "the segment.\n" "\n" - "Currently SubX assumes the first segment encountered contains executable code, and\n" - "the second contains global variables. By convention we call them 'code' and 'data'\n" - "respectively.\n" - "The first instruction executed in the resulting binary is always the first\n" - "instruction of the first segment.\n" + "The first segment contains code and should be called 'code'.\n" + "The second segment should be called 'data'.\n" + "The resulting binary starts running from the start of the code segment by default.\n" + "To start elsewhere in the code segment, define a special label called 'Entry'.\n" "\n" "Segments with the same name get merged together. This rule helps keep functions and\n" "their data close together in .subx files.\n" - "Later segments with the same name get their contents *prepended* to earlier ones.\n" - "This rule helps each .subx file to put forth a different entrypoint for the binary,\n" - "overriding previously loaded files.\n" "\n" "Lines consist of a series of words. Words can contain arbitrary metadata\n" "after a '/', but they can never contain whitespace. Metadata has no effect\n" @@ -184,7 +180,7 @@ void flush(program& p, vector& lines) { return; } // End flush(p, lines) Special-cases - trace(99, "parse") << "flushing to segment" << end(); + trace(99, "parse") << "flushing segment" << end(); p.segments.back().lines.swap(lines); } @@ -228,6 +224,7 @@ typedef void (*transform_fn)(program&); :(before "End Globals") vector Transform; +:(code) void transform(program& p) { trace(99, "transform") << "begin" << end(); for (int t = 0; t < SIZE(Transform); ++t) @@ -267,6 +264,7 @@ void load(const program& p) { if (i == 0) End_of_program = addr; } EIP = p.segments.at(0).start; + // End Initialize EIP trace(99, "load") << "done" << end(); } diff --git a/subx/028translate.cc b/subx/028translate.cc index 2104d57b..d4b1a3a5 100644 --- a/subx/028translate.cc +++ b/subx/028translate.cc @@ -97,13 +97,14 @@ void write_elf_header(ostream& out, const program& p) { // e_version O(0x01); O(0x00); O(0x00); O(0x00); // e_entry - int e_entry = p.segments.at(0).start; // convention + uint32_t e_entry = p.segments.at(0).start; // convention + // Override e_entry emit(e_entry); // e_phoff -- immediately after ELF header - int e_phoff = 0x34; + uint32_t e_phoff = 0x34; emit(e_phoff); // e_shoff; unused - int dummy32 = 0; + uint32_t dummy32 = 0; emit(dummy32); // e_flags; unused emit(dummy32); diff --git a/subx/034compute_segment_address.cc b/subx/034compute_segment_address.cc index d37060a4..2798e040 100644 --- a/subx/034compute_segment_address.cc +++ b/subx/034compute_segment_address.cc @@ -17,8 +17,6 @@ //: Update the parser to handle non-numeric segment name. //: //: We'll also support repeated segments with non-numeric names. -//: When we encounter a new reference to an existing segment we'll *prepend* -//: the new data to existing data for the segment. :(before "End Globals") map Segment_index; @@ -46,7 +44,7 @@ if (!starts_with(segment_title, "0x")) { out.segments.push_back(segment()); } else { - trace(99, "parse") << "prepending to segment '" << segment_title << "'" << end(); + trace(99, "parse") << "appending to segment '" << segment_title << "'" << end(); } Currently_parsing_segment_index = get(Segment_index, segment_title); } @@ -54,9 +52,9 @@ if (!starts_with(segment_title, "0x")) { :(before "End flush(p, lines) Special-cases") if (Currently_parsing_named_segment) { assert(!p.segments.empty()); - trace(99, "parse") << "flushing to segment" << end(); + trace(99, "parse") << "flushing segment" << end(); vector& curr_segment_data = p.segments.at(Currently_parsing_segment_index).lines; - curr_segment_data.insert(curr_segment_data.begin(), lines.begin(), lines.end()); + curr_segment_data.insert(curr_segment_data.end(), lines.begin(), lines.end()); lines.clear(); Currently_parsing_named_segment = false; Currently_parsing_segment_index = -1; @@ -69,17 +67,19 @@ if (Currently_parsing_named_segment) { == code 2d/subtract-from-EAX 0xddccbbaa/imm32 +parse: new segment 'code' -+parse: prepending to segment 'code' -+load: 0x09000054 -> 2d -+load: 0x09000055 -> aa -+load: 0x09000056 -> bb -+load: 0x09000057 -> cc -+load: 0x09000058 -> dd -+load: 0x09000059 -> 05 -+load: 0x0900005a -> 0a -+load: 0x0900005b -> 0b -+load: 0x0900005c -> 0c -+load: 0x0900005d -> 0d ++parse: appending to segment 'code' +# first segment ++load: 0x09000054 -> 05 ++load: 0x09000055 -> 0a ++load: 0x09000056 -> 0b ++load: 0x09000057 -> 0c ++load: 0x09000058 -> 0d +# second segment ++load: 0x09000059 -> 2d ++load: 0x0900005a -> aa ++load: 0x0900005b -> bb ++load: 0x0900005c -> cc ++load: 0x0900005d -> dd :(scenario error_on_missing_segment_header) % Hide_errors = true; diff --git a/subx/035labels.cc b/subx/035labels.cc index 5531910a..e86441cf 100644 --- a/subx/035labels.cc +++ b/subx/035labels.cc @@ -19,6 +19,25 @@ //: Later layers may add more conventions partitioning the space of names. But //: the above rules will remain inviolate. +//: One special label: the address to start running the program at. + +:(scenario entry_label) +== 0x1 +05 0x0d0c0b0a/imm32 +Entry: +05 0x0d0c0b0a/imm32 ++run: inst: 0x00000006 +-run: inst: 0x00000001 + +:(before "End Globals") +uint32_t Entry_address = 0; +:(before "End Reset") +Entry_address = 0; +:(before "End Initialize EIP") +if (Entry_address) EIP = Entry_address; +:(after "Override e_entry") +if (Entry_address) e_entry = Entry_address; + :(before "End looks_like_hex_int(s) Detectors") if (SIZE(s) == 2) return true; @@ -87,6 +106,8 @@ void rewrite_labels(program& p) { drop_labels(code); if (trace_contains_errors()) return; replace_labels_with_displacements(code, byte_index); + if (contains_key(byte_index, "Entry")) + Entry_address = code.start + get(byte_index, "Entry"); } void compute_byte_indices_for_labels(const segment& code, map& byte_index) { @@ -125,7 +146,7 @@ void compute_byte_indices_for_labels(const segment& code, map& raise << "'" << to_string(inst) << "': labels can only be the first word in a line.\n" << end(); if (Map_file.is_open()) Map_file << "0x" << HEXWORD << (code.start + current_byte) << ' ' << label << '\n'; - if (contains_key(byte_index, label)) { + if (contains_key(byte_index, label) && label != "Entry") { raise << "duplicate label '" << label << "'\n" << end(); return; } diff --git a/subx/050_write.subx b/subx/050_write.subx index 58cfde7c..083adad6 100644 --- a/subx/050_write.subx +++ b/subx/050_write.subx @@ -5,8 +5,8 @@ # . 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 -# main: - # syscall(exit, 0) -- can't test _write just yet +Entry: # just exit; can't test _write just yet + # . syscall(exit, 0) bb/copy-to-EBX 0/imm32 b8/copy-to-EAX 1/imm32/exit cd/syscall 0x80/imm8 diff --git a/subx/051test.subx b/subx/051test.subx index ceccc076..6f8cda7a 100644 --- a/subx/051test.subx +++ b/subx/051test.subx @@ -5,7 +5,7 @@ # . 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 -# main: (manual test if this is the last file loaded) +Entry: # manual test # check-ints-equal(34, 34) # . . push args 68/push "error in check-ints-equal"/imm32 diff --git a/subx/052kernel-string-equal.subx b/subx/052kernel-string-equal.subx index 47e1e296..55d6c50a 100644 --- a/subx/052kernel-string-equal.subx +++ b/subx/052kernel-string-equal.subx @@ -19,7 +19,7 @@ # . 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 -# main: +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 diff --git a/subx/053new-segment.subx b/subx/053new-segment.subx index fd7203b9..1669b097 100644 --- a/subx/053new-segment.subx +++ b/subx/053new-segment.subx @@ -5,7 +5,7 @@ # . 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 -# main: (manual test if this is the last file loaded) +Entry: # manual test # EAX = new-segment(0x1000) # . . push args 68/push 0x1000/imm32 diff --git a/subx/054string-equal.subx b/subx/054string-equal.subx index 607a8447..f5818e79 100644 --- a/subx/054string-equal.subx +++ b/subx/054string-equal.subx @@ -5,8 +5,7 @@ # . 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 -# main: - # run-tests() +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) diff --git a/subx/055stream.subx b/subx/055stream.subx index f5d24876..92049634 100644 --- a/subx/055stream.subx +++ b/subx/055stream.subx @@ -14,13 +14,6 @@ # . 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 -# main: - 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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - clear-stream: # f : (address stream) -> # . prolog 55/push-EBP diff --git a/subx/056trace.subx b/subx/056trace.subx index 479569a7..f181e1d7 100644 --- a/subx/056trace.subx +++ b/subx/056trace.subx @@ -41,14 +41,6 @@ _test-trace-stream: # . 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 -# main: - # run-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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - # Allocate a new segment for the trace stream, initialize its length, and save its address to Trace-stream. # The Trace-stream segment will consist of variable-length lines separated by newlines (0x0a) initialize-trace-stream: diff --git a/subx/057write.subx b/subx/057write.subx index 2a111dd3..3135003b 100644 --- a/subx/057write.subx +++ b/subx/057write.subx @@ -20,13 +20,6 @@ # . 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 -# main: - 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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - # TODO: come up with a way to signal when a write to disk fails write: # f : fd or (address stream), s : (address array byte) -> # . prolog diff --git a/subx/058stream-equal.subx b/subx/058stream-equal.subx index 203e5415..ee04d4eb 100644 --- a/subx/058stream-equal.subx +++ b/subx/058stream-equal.subx @@ -5,13 +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 -# main: +#? Entry: # run a single test, while debugging #? e8/call test-next-stream-line-equal-stops-at-newline/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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 +#? # 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 +#? b8/copy-to-EAX 1/imm32/exit +#? cd/syscall 0x80/imm8 # compare all the data in a stream (ignoring the read pointer) stream-data-equal?: # f : (address stream), s : (address string) -> EAX : boolean diff --git a/subx/059stop.subx b/subx/059stop.subx index 4478dab3..eca66bcb 100644 --- a/subx/059stop.subx +++ b/subx/059stop.subx @@ -37,13 +37,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 -# main: - e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. +#? Entry: # run a single test, while debugging #? e8/call test-stop-skips-returns-on-exit/disp32 - # 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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 +#? # 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 +#? b8/copy-to-EAX 1/imm32/exit +#? cd/syscall 0x80/imm8 # Configure an exit-descriptor for a call pushing 'nbytes' bytes of args to # the stack. diff --git a/subx/060read.subx b/subx/060read.subx index fcf38dde..9f5f7486 100644 --- a/subx/060read.subx +++ b/subx/060read.subx @@ -45,13 +45,6 @@ # . 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 -# main: - 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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - read: # f : fd or (address stream), s : (address stream) -> num-bytes-read/EAX # . prolog 55/push-EBP diff --git a/subx/061read-byte.subx b/subx/061read-byte.subx index d3192ce1..26b63e63 100644 --- a/subx/061read-byte.subx +++ b/subx/061read-byte.subx @@ -31,14 +31,13 @@ Stdin: # . 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 -# main: - e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. +#? Entry: # run a single test, while debugging #? e8/call test-read-byte-multiple/disp32 #? e8/call test-read-byte-refills-buffer/disp32 - # 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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 +#? # 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 +#? b8/copy-to-EAX 1/imm32/exit +#? cd/syscall 0x80/imm8 # return next byte value in EAX, with top 3 bytes cleared. # On EOF, return 0xffffffff. diff --git a/subx/062write-stream.subx b/subx/062write-stream.subx index b273336b..73766fe3 100644 --- a/subx/062write-stream.subx +++ b/subx/062write-stream.subx @@ -5,19 +5,15 @@ # . 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 -# main: - # manual test +#? Entry: # manual test #? # write-stream(stdout, _test-stream2) #? 68/push _test-stream2/imm32 #? 68/push 1/imm32/stdout #? e8/call write-stream/disp32 - # automatic test -#? e8/call test-write-stream-single/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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 +#? # 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 +#? b8/copy-to-EAX 1/imm32/exit +#? cd/syscall 0x80/imm8 write-stream: # f : fd or (address stream), s : (address stream) -> # . prolog diff --git a/subx/063error.subx b/subx/063error.subx index efda8ea3..db460db1 100644 --- a/subx/063error.subx +++ b/subx/063error.subx @@ -5,13 +5,6 @@ # . 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 -# main: - 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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - # write(out, "Error: "+msg+"\n") then stop(ed, 1) error: # ed : (address exit-descriptor), out : fd or (address stream), msg : (address array byte) -> # . prolog diff --git a/subx/064write-byte.subx b/subx/064write-byte.subx index 61ed4197..9f97c336 100644 --- a/subx/064write-byte.subx +++ b/subx/064write-byte.subx @@ -27,13 +27,6 @@ Stdout: # . 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 -# main: - 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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - # Write lower byte of 'n' to 'f'. write-byte: # f : (address buffered-file), n : int -> # . prolog diff --git a/subx/065hex.subx b/subx/065hex.subx index 9096680b..a5a4bdac 100644 --- a/subx/065hex.subx +++ b/subx/065hex.subx @@ -6,13 +6,6 @@ # . 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 -# main: - 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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - is-hex-int?: # in : (address slice) -> EAX : boolean # . prolog 55/push-EBP diff --git a/subx/066print-byte.subx b/subx/066print-byte.subx index 3335bcbf..39d7793e 100644 --- a/subx/066print-byte.subx +++ b/subx/066print-byte.subx @@ -5,13 +5,6 @@ # . 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 -# main: - 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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - print-byte: # f : (address buffered-file), n : int -> # . prolog 55/push-EBP diff --git a/subx/067write-buffered.subx b/subx/067write-buffered.subx index 94ed4f8a..76ae4313 100644 --- a/subx/067write-buffered.subx +++ b/subx/067write-buffered.subx @@ -5,14 +5,13 @@ # . 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 -# main: +#? Entry: # run a single test, while debugging #? e8/call test-write-buffered/disp32 #? e8/call test-write-buffered-with-intermediate-flush/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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 +#? # 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 +#? b8/copy-to-EAX 1/imm32/exit +#? cd/syscall 0x80/imm8 write-buffered: # f : (address buffered-file), msg : (address array byte) -> # pseudocode: diff --git a/subx/068error-byte.subx b/subx/068error-byte.subx index 1bf77be5..252aff20 100644 --- a/subx/068error-byte.subx +++ b/subx/068error-byte.subx @@ -5,8 +5,7 @@ # . 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 -# main: - # manual test +#? Entry: # manual test #? # . var ed/EAX : exit-descriptor #? 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # subtract from ESP #? 89/copy 3/mod/direct 0/rm32/EAX . . . 4/r32/ESP . . # copy ESP to EAX @@ -19,12 +18,10 @@ #? 68/push Stderr/imm32 #? 50/push-EAX #? e8/call error-byte/disp32 - # automatic test - 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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 +#? # . 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 +#? b8/copy-to-EAX 1/imm32/exit +#? cd/syscall 0x80/imm8 # write(out, "Error: "+msg+": "+byte) then stop(ed, 1) error-byte: # ed : (address exit-descriptor), out : (address buffered-file), msg : (address array byte), n : byte -> diff --git a/subx/069allocate.subx b/subx/069allocate.subx index 7efeb678..fe471ed9 100644 --- a/subx/069allocate.subx +++ b/subx/069allocate.subx @@ -29,13 +29,6 @@ Heap: # . 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 -# main: - 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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - # Claim the next 'n' bytes of memory starting at ad->curr and update ad->curr. # If there isn't enough memory before ad->limit, return 0 and leave 'ad' unmodified. allocate: # ad : (address allocation-descriptor), n : int -> address-or-null/EAX diff --git a/subx/070new-stream.subx b/subx/070new-stream.subx index e6f2e0cb..ad6ab68d 100644 --- a/subx/070new-stream.subx +++ b/subx/070new-stream.subx @@ -5,13 +5,6 @@ # . 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 -# main: - 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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - new-stream: # ad : (address allocation-descriptor), length : int, elemsize : int -> address/EAX # . prolog 55/push-EBP diff --git a/subx/071read-line.subx b/subx/071read-line.subx index 61513aa9..bb0c03be 100644 --- a/subx/071read-line.subx +++ b/subx/071read-line.subx @@ -3,13 +3,6 @@ # . 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 -# main: - 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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - # read bytes from 'f' until (and including) a newline and store them into 's' # return true if no data found, false otherwise # just abort if 's' is too small diff --git a/subx/072slice.subx b/subx/072slice.subx index 54049b6d..c8834719 100644 --- a/subx/072slice.subx +++ b/subx/072slice.subx @@ -6,14 +6,13 @@ # . 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 -# main: +#? Entry: # run a single test, while debugging #? e8/call test-slice-starts-with-fails/disp32 #? e8/call test-slice-starts-with-single-character/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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 +#? # 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 +#? b8/copy-to-EAX 1/imm32/exit +#? cd/syscall 0x80/imm8 slice-empty?: # s : (address slice) -> EAX : boolean # . prolog diff --git a/subx/073next-token.subx b/subx/073next-token.subx index 41dd94f3..1d37ba70 100644 --- a/subx/073next-token.subx +++ b/subx/073next-token.subx @@ -3,13 +3,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 -# main: +#? Entry: # run a single test, while debugging #? e8/call test-next-token-from-slice/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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 +#? # 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 +#? b8/copy-to-EAX 1/imm32/exit +#? cd/syscall 0x80/imm8 # extract the next run of characters that are different from a given 'delimiter' (skipping multiple delimiters if necessary) # on eof return an empty interval diff --git a/subx/Readme.md b/subx/Readme.md index f95be08b..8891e8ee 100644 --- a/subx/Readme.md +++ b/subx/Readme.md @@ -278,7 +278,7 @@ distinguish between code and data. Correspondingly, SubX programs consist of a series of segments, each starting with a header line: `==` followed by a name. The first segment must be named `code`; the second must be named `data`. -Execution always begins at the start of the `code` segment. +Execution begins at the start of the `code` segment by default. You can reuse segment names: @@ -293,17 +293,9 @@ You can reuse segment names: ...C... ``` -The code segment now contains the instructions of `A` as well as `C`. `C` -comes _before_ `A`. (Why this order? I'd like to organize SubX programs into -sequences of [_layers_](http://akkartik.name/post/wart-layers) that permit -incrementally building a subset of layers into a working program with a subset -of functionality. This organization requires, among other things, letting each -layer control the code that runs when the binary starts up. Letting each layer -override the starting address would require additional syntax. Instead, I -choose to always begin execution at the start of the code segment, but allow -layers to prepend to segments.) +The `code` segment now contains the instructions of `A` as well as `C`. -Within the code segment, each line contains a comment, label or instruction. +Within the `code` segment, each line contains a comment, label or instruction. Comments start with a `#` and are ignored. Labels should always be the first word on a line, and they end with a `:`. @@ -346,11 +338,18 @@ The latter is mostly useful for `jump` and `call` instructions. Functions are defined using labels. By convention, labels internal to functions (that must only be jumped to) start with a `$`. Any other labels must only be -called, never jumped to. +called, never jumped to. All labels must be unique. + +A special label 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. + +(The `Entry` label, along with duplicate segment headers, allows programs to +be built up incrementally out of multiple _layers_](http://akkartik.name/post/wart-layers).) The data segment consists of labels as before and byte values. Referring to -data labels in either code segment instructions or data segment values (using -the `imm32` metadata either way) yields their address. +data labels in either `code` segment instructions or `data` segment values +(using the `imm32` metadata either way) yields their address. Automatic tests are an important part of SubX, and there's a simple mechanism to provide a test harness: all functions that start with `test-` are called in diff --git a/subx/apps/crenshaw2-1 b/subx/apps/crenshaw2-1 index 99d08ba478fbbe18fb084dd7376f37ed7f008cc2..6588d8e7f4110af4a853c234cec0748c2af5dae5 100755 GIT binary patch literal 18028 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 Y;iF3viEA7K)^L&)FgA41&TX{(Kjjy36aWAK literal 18370 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

9~UQUF{bSTVU zKD*pY$*9yH0vBc1Wn9FvV0quH-13UBz(SyXSHYz8a@<7r55X7S*NQeApok{a<@lOg zrUylb#bA{AD8`yg#>!{<`;9UC2>gCOfrWn|&;u~_SppjYUIUo_9D(})yw4NZ0Pq~Z z@D~W^0Jj3{2MD}KpcUXCz}N!>E(W*;;2wat04DvFz#Rb30t|bJz#@P&z%Kw6yi8yp zK>yze-17>7Q3nZ>ze?aXfIfiSKL{KGxa&0n-+7(DE`Y-Tlinb33BY!M-vIm#V6#Es zX8_Lul)g#eJb)H}X8`^UaQ<5a)&u;MKlRb4T>!J+Ch%Q=tNuygd4RgZ1iApe^$vlP z{)JBf;dcqldXGQ`U?0HFe-oJe9|E@kEIC48KfvSf6Da+FfbS@Q^#FGQ^nXa;tYZY0 z1Ec^h`iQ_405<{b0(c!@_{Rk166mE0kUyxh{2x0m*wEPY2vsK03`50PKX#fqbNzGX zMj}_tnLB6h75=I%bLLi6&GA>w!GdD_*y&M%xCdNtF?J&^7tRy-iyzus75K4Bux_6y z4)ld+X)?J^r(arD`a$C&ciA+y1$L&iWC}yIpFcp{bb$7B8&{W7t?HRfLyk8gxUb%{hgvA{PQ1}E@dY-wzm5l^++P=Z;PZFb;`m?bU)HC`BSKn01br~Y4G_5 zp^e2;QYuI(3ywh9l-o&Jw6J2z2}t%+WfshXO}ynBiiOi5#LpN+`~Y&hx6=n#)Ls+P|L;r(Rd6;F$kkCnibT=bV;3h{nNCvb0o!uErg1cGTXno zHKhwTLFTMK8<~ibBE}jNoHPPp_$)$AGL?>3CAjE7nIa!f=9JjOG@`O#z|OXD!TPzyINBor9Iu) zs3nt@+sPAFKL7aQ((O$V+AS0|+|g^&6jX6KLDgf$A(oCt3#*Z&$5nF%nJA?vv=)lq z0v}klCMr(LG|jdFLHZW>%q}QU{Z`qVyB?De0%%ce(wbXvn3c6FI!5yF8pRoH)0$c- zI{xNpI;oRM_(L{P#3GA6kAQT{649`gf=*wMP)4-Vik0#M59g{Pj+?DXzpibe;hI9M zq~Qwf*CVl}sFw6cwG@?N($Rl5GWIQ%pxDy-$V;AM!Oo|Q(o$g&IwqfukXPKnq*!KE zZSl7!wC2_=jtz%RibWXHTBv{l1(D4I456a}iD`E1SIkbLA~s{rQyvF33?Hr8v7p$9A{0zo}W;~(gOf=J%%&ml;91BuEe^UAR=8q74#(V%vjDIn3GSr}R5ns)*| zMWUM{TWOnz-LXH?O!EsnJa9X96@%Dcn0wZ2(K2|zBD>3MeVS-dO|1@N2a?#9gKk+c!Pwl)bH=hCmtfyISQqkp58 zh-p#NE89uZA4w!4TTNRXMeu3t%3r&PS%oYpq?{d5oK20NgA*=)4mMG*)hB2vAKs}^ n*j8&LbF4&Gqzbr+)1JkP;?(e1504Ugk;67KDYA$PKj;4eR}-h_ diff --git a/subx/apps/crenshaw2-1.subx b/subx/apps/crenshaw2-1.subx index ad8dad46..8acdde59 100644 --- a/subx/apps/crenshaw2-1.subx +++ b/subx/apps/crenshaw2-1.subx @@ -30,11 +30,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 tests if necessary, call 'compile' if not + #? # for debugging: run a single test; don't bother setting status code #? e8/call test-get-num-reads-single-digit/disp32 #? eb/jump $main:end/disp8 -# main: run tests if necessary, call 'compile' if not # . prolog 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # - if argc > 1 and argv[1] == "test", then return run_tests() diff --git a/subx/apps/crenshaw2-1b b/subx/apps/crenshaw2-1b index ae66b7b4cb6f378a6e556cdf36dc8c6e9d44c4dc..08c5f45ea929ef307db98ddd2995687f69c78dd8 100755 GIT binary patch literal 18587 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 diff --git a/subx/apps/crenshaw2-1b.subx b/subx/apps/crenshaw2-1b.subx index 044221eb..55689cca 100644 --- a/subx/apps/crenshaw2-1b.subx +++ b/subx/apps/crenshaw2-1b.subx @@ -30,11 +30,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 tests if necessary, call 'compile' if not + #? # for debugging: run a single test; don't bother setting status code #? e8/call test-get-num-reads-single-digit/disp32 #? eb/jump $main:end/disp8 -# main: run tests if necessary, call 'compile' if not # . prolog 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # - if argc > 1 and argv[1] == "test", then return run_tests() diff --git a/subx/apps/factorial b/subx/apps/factorial index 901933709e64c3d80f52c67daee178dc02f2fc78..d8cd6766a06aa9e21b215b2703662727c9ecbcd0 100755 GIT binary patch literal 16946 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 literal 17288 zcmbVT34B!5xu2LJ8E}BGl!zz}3L@Y@!lq%V3?#uS;0y}5Aas)4a8rg!oP|XRGPXXQ zTw`t3Uw_?Rl~>!oSNm&Sp2n?}21WW5t-e+$>Z^4-8WnfIE${n(=iYPfolGb;zaQVs z{qDCf=R4=#;p)02^(7@GKIiW^U#SmQ8J}<9Ob1DyGkqc7arU)+pJ_lhdaBQde*hX4?tY<$+uezFsK)ueY~X(jPJc zm*wBSyj#lIt?=geNW8h3sH0-w6i5%!_ioWi->s9OTkDC&R<5$L0js^DHyd0jzCqED z23yPgowY-P`Ete&EiJ?^_OD%Y$;D7l)|zLLP!XBvcw&-1AA|hM<}YCl6HFZMNQs#t zP%w5Q8x9lA--2`qeX~k(0ym@L+{xhKyHDXRWx{7g{Lbx3>bA#}`%W)rid(BsYkiaC z_Fm!dtriD3Ur=UCi^i6(vX%y|6%|(d$mKEQbPk7tY08(!qT(@qO)izA)Gfznx@U*m z7OjVF2m&nx4ULJn&v0UE3+lS&7;Jv+OB5j6+)*I#$AtnZek)O4%ly_@YeleT zfBWF-M?0vlYM#lKMtTnBm-*M&A(O@M1(yiN>vs^&6>@N#Q#TwpiTro=D*(^CK#9a-6`6N(rU-MVa2R) zc{d1@9`9yqE2MY3PgCVSRmpuIR3vIH?`DCLJke2mfxCvilX6?N+%-yWyqMf~xhOar zO?~YBj+RSNi!HyvuG3x106N2~G7hSDyfP1c@SgNR$;z~Y-|9-A1- zG;W?Dg)!mkpXasNpK(3A&Hf%ZZ%434CtJ!ImZx!vk?{7 z_2Gm%$J%+!`JV2cMVfPIA5N%qI1T2!Pje-*s_zFy~gyd86jsf2z|D&TMh( zyo)&(YR>-#r!0w|6>=iGyti29pEAU14_cKqf4cf~Yj$oor*{t}_(08{+Xr`)b(~VO zFB^>1FYY(!|vj6 zmsNy0Cuq*an)ByJ<=n!YJvwOHHRrdE%6TVq-laM30VhHe6;(&&e4aTsY0eil=O>|p z6w?^vOa-kWXvFq_wJK<>_1C=LURCql)=++}f0g*3!C*q-Iv4w+V&%!sW%U6X=q1H+W((@$Ia@M>X!!s0h*T+);R@?cQOpF1Fm#~#`h2C|ES*I`7z4nYgN9Ls z?$DYNw8}bb%YxC)`e2k+G3?t$D2Z#l)^(iZ_~N!Mqp;>_w5bqH`ubGpX5`AzVC53T zwKRQ;QY5c$qLPxKGbe*{i8B3{Uvrx--Z`bnO1<3fA=;u-2hCj-XkR&ZnSbll&U#A2 z(_)-z15HAmj&{bYiR?9 zUN!A|5woeN(+^dyJceLsiRt9FazHU?Qo^gUB*4&P0ar#DRCjadmAmwt|u@qdqueEJ)F{=54^<2f)eM!a{Jz-UHr#B1logZqqG=m26jeuVoHX zx|1G;0z@?`?&Jz~X*fsmx;0EvSgB#OzJ49TI1a}bbNRC`u+`@JdRwcVrPP{JW)uHv z09lVCoM3c|pAl8z++S|hRa8HF$Oz^>r6~Balk;T|X{ zBgwsO0kKr!VSw06mxT_+mh(;~|Hsl5!MQR2)^Z*kJ;&vT$)bi)IAEK{6QIpODSgC5 zH=Dp=Jp_fg85J*a&9WKwXAu_XP&yOtR%mA;x&^}4m`G`X*MOCfB(PI)n!f=SYDnNl zg|-FK@)Se@&Qwxl_hu^dJ99f>WiE;@|F{MJD3 zUD^>YsXov#I`>(av}H>o@}deC!y|Nel0yT2zNl#H!vuP>%Vzoq4;(hHSu@S;!vuGfPruPj-_=ZIeVDqz^aoqhX3cb`_UX@D zz^F%0AP_=CZ;@vDi)NC&t+O<34&hPj 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 diff --git a/subx/apps/factorial.subx b/subx/apps/factorial.subx index 912285e2..8f4bf47d 100644 --- a/subx/apps/factorial.subx +++ b/subx/apps/factorial.subx @@ -18,7 +18,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 -# main: +Entry: # run tests if necessary, compute `factorial(5)` if not + +#? # for debugging: run a single test; don't bother setting status code +#? e8/call test-get-num-reads-single-digit/disp32 +#? eb/jump $main:end/disp8 + # . prolog 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # - if argc > 1 and argv[1] == "test", then return run_tests() diff --git a/subx/apps/handle b/subx/apps/handle index 5708c864a37625c0d57808ef1e765dfcbbb1ca29..fe9e4cceeff2fb192d3727916808a1eb4d6a2047 100755 GIT binary patch literal 17721 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 literal 18081 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

fi8_p!du~KYG0$Ym|i7}g2 zSDv=hIGG8f6i_l_Vtr|)*6ylws{*)Q4ZF2jh{%7!N5SJVSmnQmhO?L?8L4GPOPqR{ zETOuPtfZC@_Uy^ug+Vr9vw#t4N6EvWy3lz}rm?oRWHY3vv(3#$nhMxznW5%vDrF=x zq4p$e8A`T>EaZ4H5o$5g&8c{MCYf^WJjLv??PQ3NE=}udD~cA|TQ+5ARWR+I8gWe}YZL!o+W17=#PPA|9uu=PC zlr}QykQ|~y%}MfpbEa+8(S*$#3x=V(5LT%Zjp2xAtO;v#ONdsLYYqZyyIme@%NqDU z!W833F0O8?=)?8~nn`61-b0hEQr^Upya+$mLIX-XK}R9z8qOv%@it5;b~r<9#n{;&PORey$zO`LZ?EmbM2;R}Zj|aAvTow-gUPQaE|IHd_Y|YDdX1 z&PNtASI_X`@geL$QrS52w9nOMovifv3TUo9%!wwwq>*`lKb0s{K1ggDt5S3ZXGA$^ z@D3YmrbYz;u8J)tkz(ZW3lWPnxi-OK0yRKjA7?4@)YjDOI#U)CQfrFSO@I_7-RQ1? zViF#kS*zxuy<5(h;jykkCInmalWOoa&YN)C@`D3D+e@rxHXkr7H0h|Im7nD%ZW%LUA`*GPfHJlz72M) z$u;KU)WO-74lj#knoXM85Up5~Yi=%q6{d>a9EjZJrkp#(lF$p>kxr}7j`X4i$hrl2Cy&9Q{^ z6kJnB_oK9D##`7?mW$kh_uzYZx|)WYc|Q_|j?`S|G{KEyT?ec%=~^n?PWNBMTDzOI zOPwNWr2DXyGU?Aepj5i@T}HjWSfsmpONq2dr93P78xB@rm=2@i-b}9fj+|H#+x`Qq zqg7yy_Un!Vt5cd2=WlPpcTRLN9lhz*TkyTqXY}GVM^zPvd)UDd!km@v4(Cn{U5Zv! X@lnsJDx^w_;p!&b=;RP<-TeJOy{fLB literal 21349 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 N(sY*(S0KYD{XgWw2CV=9 diff --git a/subx/apps/hex.subx b/subx/apps/hex.subx index 49ca3bd4..4f65d03b 100644 --- a/subx/apps/hex.subx +++ b/subx/apps/hex.subx @@ -17,12 +17,13 @@ # . 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 - # for debugging: run a single test +Entry: # run tests if necessary, convert stdin if not + +#? # for debugging: run a single test #? e8/call test-skip-until-newline/disp32 #? 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX #? eb/jump $main:end/disp8 -# main: run tests if necessary, convert stdin if not # . prolog 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP # - if argc > 1 and argv[1] == "test", then return run_tests() diff --git a/subx/apps/merge.subx b/subx/apps/merge.subx deleted file mode 100644 index a5ecc987..00000000 --- a/subx/apps/merge.subx +++ /dev/null @@ -1,36 +0,0 @@ -# Read a text file of SubX segment 'fragments' with duplicate names, and emit -# a list of 'merged' segments. -# -# Example input: -# == A -# a -# b -# c -# == B -# d -# e -# == A -# f -# g -# == A -# h -# -# Output: -# == A -# h -# f -# g -# a -# b -# c -# == B -# d -# e -# -# The output gives each segment the contents of all its fragments, with later -# fragments *prepended* to earlier ones. -# -# Prepending necessitates buffering output until the end. We'll convert -# fragments to distinct streams, maintain each segment as a linked list of -# fragments that's easy to prepend to, and finally emit the linked lists in -# order. diff --git a/subx/apps/pack b/subx/apps/pack index b4d04abe1e387471a5507416c613633b605bdbd8..a16daf5b9c74cda91483340bee89e47c4c33a526 100755 GIT binary patch literal 21184 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 literal 21526 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 1 and argv[1] == "test", then return run_tests() diff --git a/subx/examples/ex10.subx b/subx/examples/ex10.subx index 7e37a54b..7b88f582 100644 --- a/subx/examples/ex10.subx +++ b/subx/examples/ex10.subx @@ -12,7 +12,7 @@ # . 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 -# main: return argv-equal(argv[1], argv[2]) +Entry: # return argv-equal(argv[1], argv[2]) # At the start of a SubX program: # argc: *ESP # argv[0]: *(ESP+4) diff --git a/subx/examples/ex11.subx b/subx/examples/ex11.subx index 071a855b..a40c68d4 100644 --- a/subx/examples/ex11.subx +++ b/subx/examples/ex11.subx @@ -19,7 +19,7 @@ # . 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 -# main: +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, EAX) 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX diff --git a/subx/examples/ex5.subx b/subx/examples/ex5.subx index 2e421fdf..f9ad9ea8 100644 --- a/subx/examples/ex5.subx +++ b/subx/examples/ex5.subx @@ -9,7 +9,8 @@ # . 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 -# main: +Entry: + # allocate x on the stack 81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # subtract from ESP