diff options
-rw-r--r-- | subx/035labels.cc | 10 | ||||
-rwxr-xr-x | subx/apps/factorial | bin | 410 -> 455 bytes | |||
-rw-r--r-- | subx/apps/factorial.subx | 35 |
3 files changed, 37 insertions, 8 deletions
diff --git a/subx/035labels.cc b/subx/035labels.cc index fc2ccd8c..207b09b1 100644 --- a/subx/035labels.cc +++ b/subx/035labels.cc @@ -89,6 +89,8 @@ void compute_byte_indices_for_labels(const segment& code, map<string, int32_t>& raise << "'" << to_string(inst) << "': label definition (':') not allowed in operand\n" << end(); if (j > 0) raise << "'" << to_string(inst) << "': labels can only be the first word in a line.\n" << end(); + if (Dump_map) + cerr << "0x" << HEXWORD << (code.start + current_byte) << ' ' << label << '\n'; put(byte_index, label, current_byte); trace(99, "transform") << "label '" << label << "' is at address " << (current_byte+code.start) << end(); // no modifying current_byte; label definitions won't be in the final binary @@ -97,6 +99,14 @@ void compute_byte_indices_for_labels(const segment& code, map<string, int32_t>& } } +:(before "End Globals") +bool Dump_map = false; // currently used only by 'subx translate' +:(before "End Commandline Options") +else if (is_equal(*arg, "--map")) { + Dump_map = true; +} + +:(code) void drop_labels(segment& code) { for (int i = 0; i < SIZE(code.lines); ++i) { line& inst = code.lines.at(i); diff --git a/subx/apps/factorial b/subx/apps/factorial index 07c92714..1d61ad03 100755 --- a/subx/apps/factorial +++ b/subx/apps/factorial Binary files differdiff --git a/subx/apps/factorial.subx b/subx/apps/factorial.subx index 9aef6634..36bc90f8 100644 --- a/subx/apps/factorial.subx +++ b/subx/apps/factorial.subx @@ -89,9 +89,28 @@ test_factorial: e8/call factorial/disp32 # discard arg 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add 4 to ESP - # if EAX == 120 - 3d/compare . . . . . . . 0x78/imm32/120 # compare EAX with 120 - 75/jump-if-unequal . . . . . . $test_factorial:else/disp8 + # check_ints_equal(EAX, 120, failure message) + # push args + 50/push-EAX + 68/push 0x78/imm32/expected-120 + 68/push "F - test_factorial"/imm32 + # call + e8/call check_ints_equal/disp32 + # discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add 12 to ESP + # end + c3/return + +## helpers + +# print msg to stderr if a != b, otherwise print "." +check_ints_equal: # (a : int, b : int, msg : (address array byte)) -> boolean + # load args into EAX, EBX and ECX + 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none . 0/r32/EAX 0xc/disp8 . # copy *(ESP+12) to EAX + 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none . 3/r32/EBX 0x8/disp8 . # copy *(ESP+8) to EBX + # if EAX == b/EBX + 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX + 75/jump-if-unequal $check_ints_equal:else/disp8 # print('.') # push args 68/push "."/imm32 @@ -102,10 +121,12 @@ test_factorial: # return c3/return # else: -$test_factorial:else: - # print('F') +$check_ints_equal:else: + # copy msg into ECX + 8b/copy 1/mod/*+disp8 4/rm32/sib 4/base/ESP 4/index/none . 1/r32/ECX 4/disp8 . # copy *(ESP+4) to ECX + # print(ECX) # push args - 68/push "F"/imm32 + 51/push-ECX # call e8/call write_stderr/disp32 # discard arg @@ -113,8 +134,6 @@ $test_factorial:else: # end c3/return -## helpers - # compare two null-terminated ascii strings # reason for the name: the only place we should have null-terminated ascii strings is from commandline args argv_equal: # (s1, s2) : null-terminated ascii strings -> EAX : boolean |