Step 569: add disassembly register view model

This commit is contained in:
Bill
2026-02-17 10:52:08 -07:00
parent e5e24c750f
commit 27a5498083
4 changed files with 324 additions and 0 deletions

View File

@@ -0,0 +1,125 @@
#pragma once
// Step 569: Disassembly + Register View Baseline
#include <algorithm>
#include <cstdint>
#include <map>
#include <string>
#include <vector>
struct DisassemblyInstruction {
std::uint64_t address = 0;
std::string opcode;
std::string operands;
bool isCurrentInstruction = false;
};
struct RegisterValue {
std::string name;
std::uint64_t value = 0;
};
class DisassemblyRegisterViewModel {
public:
bool setInstructions(const std::vector<DisassemblyInstruction>& instructions, std::string* error) {
if (!error) return false;
error->clear();
if (instructions.empty()) return fail(error, "instruction_list_empty");
for (const auto& instruction : instructions) {
if (instruction.address == 0) return fail(error, "instruction_address_invalid");
if (instruction.opcode.empty()) return fail(error, "instruction_opcode_missing");
}
instructions_ = instructions;
std::stable_sort(instructions_.begin(),
instructions_.end(),
[](const DisassemblyInstruction& a, const DisassemblyInstruction& b) {
return a.address < b.address;
});
clearCurrentIp();
return true;
}
bool setCurrentInstructionPointer(std::uint64_t address, std::string* error) {
if (!error) return false;
error->clear();
if (address == 0) return fail(error, "instruction_pointer_invalid");
bool found = false;
clearCurrentIp();
for (auto& instruction : instructions_) {
if (instruction.address == address) {
instruction.isCurrentInstruction = true;
found = true;
break;
}
}
if (!found) return fail(error, "instruction_pointer_not_found");
return true;
}
std::vector<DisassemblyInstruction> windowAroundAddress(std::uint64_t centerAddress,
std::size_t radius) const {
std::vector<DisassemblyInstruction> window;
if (instructions_.empty()) return window;
std::size_t centerIndex = instructions_.size();
for (std::size_t i = 0; i < instructions_.size(); ++i) {
if (instructions_[i].address == centerAddress) {
centerIndex = i;
break;
}
}
if (centerIndex == instructions_.size()) return window;
const std::size_t begin = centerIndex > radius ? centerIndex - radius : 0;
const std::size_t end = std::min(instructions_.size(), centerIndex + radius + 1);
for (std::size_t i = begin; i < end; ++i) window.push_back(instructions_[i]);
return window;
}
bool setRegisterValue(const std::string& registerName,
std::uint64_t value,
std::string* error) {
if (!error) return false;
error->clear();
if (registerName.empty()) return fail(error, "register_name_missing");
registers_[registerName] = value;
return true;
}
bool hasRegister(const std::string& registerName) const {
return registers_.count(registerName) != 0;
}
std::uint64_t registerValueOrZero(const std::string& registerName) const {
auto it = registers_.find(registerName);
if (it == registers_.end()) return 0;
return it->second;
}
std::vector<RegisterValue> sortedRegisters() const {
std::vector<RegisterValue> out;
for (const auto& kv : registers_) out.push_back({kv.first, kv.second});
std::stable_sort(out.begin(), out.end(), [](const RegisterValue& a, const RegisterValue& b) {
return a.name < b.name;
});
return out;
}
const std::vector<DisassemblyInstruction>& instructions() const { return instructions_; }
private:
std::vector<DisassemblyInstruction> instructions_;
std::map<std::string, std::uint64_t> registers_;
static bool fail(std::string* error, const char* code) {
*error = code;
return false;
}
void clearCurrentIp() {
for (auto& instruction : instructions_) instruction.isCurrentInstruction = false;
}
};