diff options
author | Kartik Agaram <vc@akkartik.com> | 2018-09-29 12:06:28 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2018-09-29 17:44:50 -0700 |
commit | ef79039287b7a76f4fcb0628a6295582d8caf768 (patch) | |
tree | 15cccf34d0a8a451c95e16bb8ae05e2e389d4fd1 /subx | |
parent | 8fb01417031f2c6eaa8af505112ed1bb1a51ea21 (diff) | |
download | mu-ef79039287b7a76f4fcb0628a6295582d8caf768.tar.gz |
4616 - fix subx/examples/ex7
It was broken since I added support for global variables, back on Sep 1. One other subtle thing I've improved is the name `looks_like_hex_int`. We can now distinguish in the pack-operands transform between ignoring 'foo' because it doesn't look like a number, and immediately flagging '0xfoo' as an error because it *should* be a number.
Diffstat (limited to 'subx')
-rw-r--r-- | subx/030---operands.cc | 28 | ||||
-rw-r--r-- | subx/032check_operand_bounds.cc | 2 | ||||
-rw-r--r-- | subx/035labels.cc | 31 | ||||
-rw-r--r-- | subx/036global_variables.cc | 2 | ||||
-rwxr-xr-x | subx/examples/ex7 | bin | 313 -> 313 bytes |
5 files changed, 51 insertions, 12 deletions
diff --git a/subx/030---operands.cc b/subx/030---operands.cc index f4602581..a9c85778 100644 --- a/subx/030---operands.cc +++ b/subx/030---operands.cc @@ -247,9 +247,10 @@ void add_imm_bytes(const line& in, line& out) { void emit_hex_bytes(line& out, const word& w, int num) { assert(num <= 4); - if (num == 1 || !is_hex_int(w.data)) { - out.words.push_back(w); - if (is_hex_int(w.data)) + bool is_number = looks_like_hex_int(w.data); + if (num == 1 || !is_number) { + out.words.push_back(w); // preserve existing metadata + if (is_number) out.words.back().data = hex_byte_to_string(parse_int(w.data)); return; } @@ -354,13 +355,22 @@ b9 0x080490a7/imm32 # copy to ECX # instruction effective address operand displacement immediate # 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 - bb foo/imm32 # copy foo to EBX + bb foo/imm32 # copy to EBX +transform: packing instruction 'bb foo/imm32' # no change (we're just not printing metadata to the trace) +transform: instruction after packing: 'bb foo' $error: 0 :(scenarios run) +:(scenario pack_flags_bad_hex) +% Hide_errors = true; +== 0x1 +# instruction effective address operand displacement immediate +# 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 + bb 0xfoo/imm32 # copy to EBX ++error: not a number: 0xfoo + //:: helpers :(code) @@ -424,12 +434,12 @@ word metadata(const line& inst, const string& m) { assert(false); } -bool is_hex_int(const string& s) { +bool looks_like_hex_int(const string& s) { if (s.empty()) return false; - size_t pos = 0; - if (s.at(0) == '-' || s.at(0) == '+') pos++; - if (s.substr(pos, pos+2) == "0x") pos += 2; - return s.find_first_not_of("0123456789abcdefABCDEF", pos) == string::npos; + if (s.at(0) == '-' || s.at(0) == '+') return true; + if (isdigit(s.at(0))) return true; // includes '0x' prefix + // End looks_like_hex_int(s) Detectors + return false; } :(code) diff --git a/subx/032check_operand_bounds.cc b/subx/032check_operand_bounds.cc index 69daeb46..966913e9 100644 --- a/subx/032check_operand_bounds.cc +++ b/subx/032check_operand_bounds.cc @@ -39,7 +39,7 @@ void check_operand_bounds(const segment& code) { void check_operand_bounds(const word& w) { for (map<string, uint32_t>::iterator p = Operand_bound.begin(); p != Operand_bound.end(); ++p) { if (!has_operand_metadata(w, p->first)) continue; - if (!is_hex_int(w.data)) continue; // later transforms are on their own to do their own bounds checking + if (!looks_like_hex_int(w.data)) continue; // later transforms are on their own to do their own bounds checking int32_t x = parse_int(w.data); if (x >= 0) { if (static_cast<uint32_t>(x) >= p->second) diff --git a/subx/035labels.cc b/subx/035labels.cc index 96668075..ddaeabad 100644 --- a/subx/035labels.cc +++ b/subx/035labels.cc @@ -18,6 +18,34 @@ //: be a single character long. 'a' is not a hex number, it's a variable. //: Later layers may add more conventions partitioning the space of names. But //: the above rules will remain inviolate. + +:(before "End looks_like_hex_int(s) Detectors") +if (SIZE(s) == 2) return true; + +:(scenarios transform) +:(scenario pack_immediate_ignores_single_byte_nondigit_operand) +== 0x1 +b9/copy a/imm32 # copy to ECX ++transform: packing instruction 'b9/copy a/imm32' +# no change (we're just not printing metadata to the trace) ++transform: instruction after packing: 'b9 a' + +:(scenario pack_immediate_ignores_3_hex_digit_operand) +== 0x1 +b9/copy aaa/imm32 # copy to ECX ++transform: packing instruction 'b9/copy aaa/imm32' +# no change (we're just not printing metadata to the trace) ++transform: instruction after packing: 'b9 aaa' + +:(scenario pack_immediate_ignores_non_hex_operand) +== 0x1 +b9/copy xxx/imm32 # copy to ECX ++transform: packing instruction 'b9/copy xxx/imm32' +# no change (we're just not printing metadata to the trace) ++transform: instruction after packing: 'b9 xx' + +//: a helper we'll find handy later +:(code) void check_valid_name(const string& s) { if (s.empty()) { raise << "empty name!\n" << end(); @@ -35,7 +63,8 @@ void check_valid_name(const string& s) { raise << "'" << s << "' is two characters long which can look like raw hex bytes at a glance; use a different name\n" << end(); } -:(scenarios transform) +//: Now that that's done, let's start using names as labels. + :(scenario map_label) == 0x1 # instruction effective address operand displacement immediate diff --git a/subx/036global_variables.cc b/subx/036global_variables.cc index c565014f..f278ee29 100644 --- a/subx/036global_variables.cc +++ b/subx/036global_variables.cc @@ -4,7 +4,7 @@ //: However, they can only be used in imm32 and not disp32 operands. And they //: can't be used with jump and call instructions. //: -//: This layer much the same structure as rewriting labels. +//: This layer has much the same structure as rewriting labels. :(scenario global_variable) == code diff --git a/subx/examples/ex7 b/subx/examples/ex7 index 39f6f98d..d756271e 100755 --- a/subx/examples/ex7 +++ b/subx/examples/ex7 Binary files differ |