diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2018-01-24 20:33:52 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2018-01-24 20:33:52 -0800 |
commit | 631de5d9819531e7428a115e81c8e5e627609f52 (patch) | |
tree | 16c284055e58745960ae01c6d2929b75caa87291 | |
parent | 070b4642fc7330745bb5f023be948e3ad479069c (diff) | |
download | mu-631de5d9819531e7428a115e81c8e5e627609f52.tar.gz |
4188
-rw-r--r-- | subx/014index_addressing.cc | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/subx/014index_addressing.cc b/subx/014index_addressing.cc index 826a488f..8e032f38 100644 --- a/subx/014index_addressing.cc +++ b/subx/014index_addressing.cc @@ -14,6 +14,12 @@ :(before "End Mod 0 Special-cases") case 4: // exception: mod 0b00 rm 0b100 => incoming SIB (scale-index-base) byte + uint32_t addr = effective_address_from_sib(mod); + if (addr == 0) break; + result = reinterpret_cast<int32_t*>(&Mem.at(addr)); + break; +:(code) +uint32_t effective_address_from_sib(uint8_t mod) { uint8_t sib = next(); uint8_t base = sib&0x7; if (base == EBP) { @@ -34,21 +40,21 @@ case 4: // exception: mod 0b00 rm 0b100 => incoming SIB (scale-index-base) byte // // That's the only option that makes sense for 32-bit displacement (mod 10) raise << "base 5 (often but not always EBP) not supported in SIB byte\n" << end(); - break; + return 0; } uint8_t index = (sib>>3)&0x7; if (index == ESP) { // ignore index and scale trace(2, "run") << "effective address is mem at address 0x" << std::hex << Reg[base].u << " (" << rname(base) << ")" << end(); - result = reinterpret_cast<int32_t*>(&Mem.at(Reg[base].u)); + return Reg[base].u; } else { uint8_t scale = (1 << (sib>>6)); - uint32_t addr = Reg[base].u + Reg[index].u*scale; // TODO: should the index register be treated as a signed int? + uint32_t addr = Reg[base].u + Reg[index].i*scale; // treat index register as signed. Maybe base as well? But we'll always ensure it's non-negative. trace(2, "run") << "effective address is mem at address 0x" << std::hex << addr << " (" << rname(base) << " + " << rname(index) << "*" << NUM(scale) << ")" << end(); - result = reinterpret_cast<int32_t*>(&Mem.at(addr)); + return addr; } - break; +} :(scenario add_r32_to_mem_at_base_r32_index_r32) % Reg[3].i = 0x10; // source |