From fe722b9304052b7a0a67fe01633c24ba5b4cdafa Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Sun, 18 Oct 2020 18:38:26 +0200 Subject: Implemented insertAddresses() --- asm/segment.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'asm/segment.cpp') diff --git a/asm/segment.cpp b/asm/segment.cpp index 9fb7a52..a4544f2 100644 --- a/asm/segment.cpp +++ b/asm/segment.cpp @@ -2,6 +2,11 @@ #include "operators.h" +#include + +#include +#include + using namespace std::string_literals; size_t Segment::getAddressOfLabel(const std::string& label) @@ -16,9 +21,22 @@ size_t Segment::getAddressOfLabel(const std::string& label) return address; } } + i++; } - throw std::runtime_error("Bad label: "s + label); + throw std::runtime_error("Error: Label |"s + label + "| not found."s); +} + +size_t Segment::getAddressOfIndex(size_t index) +{ + if (index >= size()) + throw std::runtime_error("Error: Index |"s + std::to_string(index) + "| not found."s); + + size_t address{0}; + for (size_t i = 0; i < index; i++) { + address += (*this)[i]->size(); + } + return address; } std::vector Segment::getCode() @@ -33,9 +51,34 @@ std::vector Segment::getCode() void Segment::insertAddresses() { + // insert relative addresses + for (size_t i = 0; i < this->size(); i++) { + try { + AddressFeature& af { dynamic_cast(*((*this)[i]))}; + + if (af.relativeAddressing == false) + throw std::runtime_error("Error: Absolute Addressing not supported."); + + int64_t target_address = getAddressOfLabel(af.label); // throws if label not found + int64_t start_address = getAddressOfIndex(i); // throws if out of range + int64_t diff = target_address - start_address; + uint64_t udiff = static_cast(diff); + if (af.addr_size == 1) { + if (diff < -128 || diff > 127) + throw std::runtime_error("Error: Address too far."s); + af.machine_code[af.addr_offs] = static_cast(udiff); + } else if (af.addr_size == 4) { + *(reinterpret_cast(af.machine_code.data() + af.addr_offs)) = boost::endian::native_to_little(static_cast(udiff)); + } else + throw std::runtime_error("Error: unexpected addr_size: "s + std::to_string(af.addr_size)); + } catch (const std::bad_cast& ex) { + // ignore, expected for non-addressing chunks + } + } } void Segment::optimize() { // TODO } + -- cgit v1.2.3