自制虚拟机(C/C++)(二、分析引导扇区,虚拟机读二进制文件img软盘)

先修复上一次的bug,添加新指令,并增加图形界面

#include <graphics.h>
#include <conio.h>
#include <windows.h>
#include <commdlg.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <thread>
#include <mutex>
#include <functional>
#include <vector>
#include <string>
#include <map>


void VM(const std::string& file);
// 虚拟机配置结构体
struct VMConfig {
    std::string name;
    std::string asmPath;
};

// 全局配置存储
std::map<std::string, VMConfig> vmConfigs;
const char* CONFIG_FILE = "vm.dll";

// 图形界面尺寸参数
const int WIDTH = 800;
const int HEIGHT = 600;
const int BTN_WIDTH = 200;
const int BTN_HEIGHT = 40;

// 当前操作状态
enum class AppState {
    MAIN_MENU,
    CREATE_VM,
    OPEN_VM,
    SETTINGS
};
AppState currentState = AppState::MAIN_MENU;

char vmNameInput[64] = {0};
char asmPathInput[256] = {0};



// 初始化图形界面
void InitGUI() {
    initgraph(WIDTH, HEIGHT);
    setbkcolor(WHITE);
    cleardevice();
    settextcolor(BLACK);
    settextstyle(30, 0, "宋体");
}

// 保存配置到文件
void SaveConfig() {
    std::ofstream fout(CONFIG_FILE);
    for (auto it = vmConfigs.begin(); it!= vmConfigs.end(); ++it) {
        fout << it->first << std::endl;
        fout << it->second.asmPath << std::endl;
    }
    fout.close();
}

// 加载配置文件
void LoadConfig() {
    vmConfigs.clear();
    std::ifstream fin(CONFIG_FILE);
    std::string name, path;
    while (std::getline(fin, name) && std::getline(fin, path)) {
        vmConfigs[name] = {name, path};
    }
    fin.close();
}

// 绘制主界面
void DrawMainMenu() {
    cleardevice();

    // 绘制标题
    settextcolor(BLUE);
    outtextxy(100, 50, "VMwork 虚拟机");

    // 绘制按钮
    setfillcolor(LIGHTGRAY);

    // 新建虚拟机按钮
    fillroundrect(300, 150, 300 + BTN_WIDTH, 150 + BTN_HEIGHT, 5, 5);
    outtextxy(330, 155, "新建虚拟机");

    // 打开虚拟机按钮
    fillroundrect(300, 250, 300 + BTN_WIDTH, 250 + BTN_HEIGHT, 5, 5);
    outtextxy(330, 255, "打开虚拟机");

    // 设置按钮
    fillroundrect(300, 350, 300 + BTN_WIDTH, 350 + BTN_HEIGHT, 5, 5);
    outtextxy(350, 355, "设置");
}

// 文件选择对话框封装
std::string SelectFile() {
    OPENFILENAMEA ofn;
    char szFile[260] = {0};

    ZeroMemory(&ofn, sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.lpstrFile = szFile;
    ofn.nMaxFile = sizeof(szFile);
    ofn.lpstrFilter = "ASM Files (*.asm)\0*.asm\0All Files (*.*)\0*.*\0";
    ofn.nFilterIndex = 1;
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;

    if (GetOpenFileNameA(&ofn)) {
        return szFile;
    }
    return "";
}

// 输入框处理函数
bool InputBox(const char* title, char* buffer, int bufferSize) {
    char prompt[10] = "";
    // 这里直接调用 easyx 的 InputBox 函数,按照其参数要求传递
    return InputBox(buffer, bufferSize, prompt, title); 
}

// 创建虚拟机流程
void CreateVMProcess() {
    // 第一步:选择ASM文件
    std::string asmPath = SelectFile();
    if (asmPath.empty()) return;

    // 第二步:输入虚拟机名称
    if (!InputBox("输入虚拟机名称", vmNameInput, sizeof(vmNameInput))) return;

    // 保存配置
    vmConfigs[vmNameInput] = {vmNameInput, asmPath};
    SaveConfig();

}

void OpenVMProcess() {
    LoadConfig();

    // 创建选择列表
    cleardevice();
    settextcolor(BLACK);
    outtextxy(50, 50, "选择虚拟机:");

    // 绘制虚拟机列表
    int y = 100;
    for (auto it = vmConfigs.begin(); it!= vmConfigs.end(); ++it) {
        std::string text = it->first + " (" + it->second.asmPath + ")";
        outtextxy(100, y, text.c_str());
        y += 50;
    }

    // 等待用户选择
    int choice = 0;
    while (true) {
        if (MouseHit()) {
            MOUSEMSG msg = GetMouseMsg();
            if (msg.uMsg == WM_LBUTTONDOWN) {
                int clickY = msg.y;
                int index = 0;
                for (auto it = vmConfigs.begin(); it!= vmConfigs.end(); ++it) {
                    int itemTop = 100 + index * 40;
                    if (clickY > itemTop && clickY < itemTop + 50) {
                        choice = index + 1;
                        break;
                    }
                    index++;
                }
            }
        }
        if (choice!= 0) break;
    }

    // 启动选定虚拟机
    if (choice > 0 && choice <= vmConfigs.size()) {
        auto it = vmConfigs.begin();
        std::advance(it, choice - 1);
        std::string selectedAsmPath = it->second.asmPath;
        VM(selectedAsmPath);
    }
}

void SetVMProcess() {
    LoadConfig();
    cleardevice();
    cleardevice();
    settextcolor(BLACK);
    outtextxy(30, 50, "虚拟机");
    outtextxy(50, 90, "处理器  : 1");
    outtextxy(50, 130, "内存    : 64KB");
    outtextxy(50, 170,"启动方式: 软盘");
    outtextxy(50, 210,"光盘    : 无");
    outtextxy(50, 250,"BIOS    : VMwork");
    outtextxy(50, 290,"方式    : .ASM");
    while(1) {
    	
	}

    
}

// 主消息循环
void MainLoop() {
	AppState prevState = AppState::MAIN_MENU; 
    while (true) {
        if (MouseHit()) {
            MOUSEMSG msg = GetMouseMsg();
            if (msg.uMsg == WM_LBUTTONDOWN) {
                // 主界面按钮处理
                if (currentState == AppState::MAIN_MENU) {
                    if (msg.x > 300 && msg.x < 300 + BTN_WIDTH) {
                        if (msg.y > 150 && msg.y < 150 + BTN_HEIGHT) {
                            CreateVMProcess();
                        } else if (msg.y > 250 && msg.y < 250 + BTN_HEIGHT) {
                            OpenVMProcess();
                        } else if (msg.y > 350 && msg.y < 350 + BTN_HEIGHT) {
                            SetVMProcess(); 
                        }
                    }
                }
            }
        }

        switch (currentState) {
            case AppState::MAIN_MENU:
                if (prevState!= AppState::MAIN_MENU) {
                    //cleardevice();
                }
                DrawMainMenu();
                break;
            case AppState::CREATE_VM:
                if (prevState!= AppState::CREATE_VM) {
                    //cleardevice();
                }
                DrawMainMenu();
                break;
            case AppState::OPEN_VM:
                if (prevState!= AppState::OPEN_VM) {
                    //cleardevice();
                }
                DrawMainMenu();
                break;
            case AppState::SETTINGS:
                if (prevState!= AppState::SETTINGS) {
                    //cleardevice();
                }
                DrawMainMenu();
                break;
        }

        prevState = currentState;

        Sleep(30);
    }
}

// 寄存器声明
unsigned char al = 0, ah = 0, bl = 0, bh = 0, cl = 0, ch = 0, dl = 0, dh = 0, si = 0;
unsigned short ax = 0, bx = 0, cx = 0, dx = 0, sp = 0x8000, bp = 0;
unsigned int org = 0, end_times = 0, end_AA55 = 0;
bool ZF = false, CF = false, SF = false; // 标志寄存器

// 标签和指令指针
std::unordered_map<std::string, size_t> labels;
size_t current_line = 0;
size_t new_current_line;
std::vector<std::string> program_lines;

// 内存模拟
std::vector<unsigned char> memory(0x10000, 0); // 64KB内存


std::mutex fileMutex;
std::ifstream file;

// 线程函数,用于读取文件
void readFile(const std::string& filename) {
    std::ifstream localFile(filename, std::ios::binary);
    if (localFile.is_open()) {
        const size_t bufferSize = 4096; // 每块读取4KB,可以根据需要调整
        char buffer[bufferSize];
        std::string currentLine;
        while (localFile.read(buffer, bufferSize)) {
            for (size_t i = 0; i < localFile.gcount(); ++i) {
                if (buffer[i] == '\n') {
                    size_t commentPos = currentLine.find(';');
                    if (commentPos!= std::string::npos) {
                        currentLine = currentLine.substr(0, commentPos);
                    }
                    while (!currentLine.empty() && std::isspace(currentLine.front())) {
                        currentLine.erase(currentLine.begin());
                    }
                    while (!currentLine.empty() && std::isspace(currentLine.back())) {
                        currentLine.erase(currentLine.length() - 1);
                    }
                    if (!currentLine.empty()) {
                        std::lock_guard<std::mutex> lock(fileMutex);
                        program_lines.push_back(currentLine);
                    }
                    currentLine.clear();
                } else {
                    currentLine += buffer[i];
                }
            }
        }
        // 处理剩余的行
        size_t commentPos = currentLine.find(';');
        if (commentPos!= std::string::npos) {
            currentLine = currentLine.substr(0, commentPos);
        }
        while (!currentLine.empty() && std::isspace(currentLine.front())) {
            currentLine.erase(currentLine.begin());
        }
        while (!currentLine.empty() && std::isspace(currentLine.back())) {
            currentLine.erase(currentLine.length() - 1);
        }
        if (!currentLine.empty()) {
            std::lock_guard<std::mutex> lock(fileMutex);
            program_lines.push_back(currentLine);
        }
        localFile.close();
    } else {
        std::cerr << "无法打开文件" << std::endl;
    }
}

// 图形输出参数
int textX = 0;
int textY = 48;
const int CHAR_WIDTH = 8;
const int LINE_HEIGHT = 16;
bool graphicsInitialized = false;

// 指令解析错误枚举
enum class InstructionError {
    INVALID_OPCODE,
    INVALID_OPERAND,
    LABEL_NOT_FOUND,
    UNKNOWN_INTERRUPT,
    OTHER_ERROR
};



// 输出错误信息到终端
void printError(const InstructionError& error, const std::string& details = "") {
    std::cerr << "ERROR: ";
    switch (error) {
    case InstructionError::INVALID_OPCODE:
        std::cerr << "无效的操作码";
        break;
    case InstructionError::INVALID_OPERAND:
        std::cerr << "无效的操作数";
        break;
    case InstructionError::LABEL_NOT_FOUND:
        std::cerr << "标签未找到";
        break;
    case InstructionError::UNKNOWN_INTERRUPT:
        std::cerr << "未知的中断号";
        break;
    case InstructionError::OTHER_ERROR:
        std::cerr << "其他错误";
        break;
    }
    if (!details.empty()) {
        std::cerr << " - " << details;
    }
    std::cerr << std::endl;
}


int parseImmediate(const std::string& immediateStr) {
    std::string result;
    bool inQuote = false;
    char quoteChar = '\0';

    for (size_t i = 0; i < immediateStr.size(); ++i) {
        const char c = immediateStr[i];
        if (c == '\'' || c == '"') {
            if (!inQuote) {
                inQuote = true;
                quoteChar = c;
                result += c;
            } else if (c == quoteChar) {
                inQuote = false;
                result += c;
            } else {
                result += c;
            }
        } else if (inQuote) {
            // 直接将引号内的字符添加到结果中,包括空格
            result += c;
        } else if (!std::isspace(c)) {
            // 非空格且不在引号内,将字符添加到结果中
            result += c;
        } else if (i > 0 &&!std::isspace(result.back())) {
            // 如果前一个字符不是空格,添加当前字符以保留中间的空格
            result += c;
        }
    }

    // 去除结果字符串两端可能残留的空格
    while (!result.empty() && std::isspace(result.front())) {
        result.erase(result.begin());
    }
    while (!result.empty() && std::isspace(result.back())) {
        result.erase(result.length() - 1);
    }

    if (result.empty()) return 0;
    if (result.length() == 3 && result[0] == '\'' && result[2] == '\'') {
        return static_cast<int>(result[1]);
    }
    else if (result.find("0x") == 0) {
        try {
            return std::stoi(result.substr(2), nullptr, 16);
        } catch (const std::invalid_argument& e) {
            throw std::invalid_argument("无效的十六进制立即数:" + result);
        } catch (const std::out_of_range& e) {
            throw std::out_of_range("十六进制立即数超出范围:" + result);
        }
    }
    else if (result.back() == 'h') {
        try {
            return std::stoi(result.substr(0, result.length() - 1), nullptr, 16);
        } catch (const std::invalid_argument& e) {
            throw std::invalid_argument("无效的十六进制立即数(以h结尾):" + result);
        } catch (const std::out_of_range& e) {
            throw std::out_of_range("十六进制立即数(以h结尾)超出范围:" + result);
        }
    }
    else {
        try {
            return std::stoi(result);
        } catch (const std::invalid_argument& e) {
            throw std::invalid_argument("无效的立即数:" + result);
        } catch (const std::out_of_range& e) {
            throw std::out_of_range("立即数超出范围:" + result);
        }
    }
}


std::unordered_map<std::string, unsigned char*>& createRegister8BitMap() {
    static std::unordered_map<std::string, unsigned char*> map = {
        {"al", &al}, {"ah", &ah}, {"bl", &bl}, {"bh", &bh},
        {"cl", &cl}, {"ch", &ch}, {"dl", &dl}, {"dh", &dh},
        {"si", &si}
    };
    return map;
}

std::unordered_map<std::string, unsigned short*>& createRegister16BitMap() {
    static std::unordered_map<std::string, unsigned short*> map = {
        {"ax", &ax}, {"bx", &bx}, {"cx", &cx}, {"dx", &dx},
        {"sp", &sp}, {"bp", &bp}
    };
    return map;
}

void UpdateTextPosition() {
    textX += CHAR_WIDTH;
    if (textX > 620) {
        textX = 20;
        textY += LINE_HEIGHT;
    }
    if (textY + LINE_HEIGHT > 480) {
        cleardevice();
        textX = 0;
        textY = 0;
    }
}

void MovInstruction(const std::string& line) {
    std::string processedLine = line;
    std::replace(processedLine.begin(), processedLine.end(), ',', ' ');
    std::istringstream iss(processedLine);
    std::string opcode, dest, src;
    iss >> opcode >> dest >> src;

    auto& reg8 = createRegister8BitMap();
    auto& reg16 = createRegister16BitMap();

    auto parseOperand = [&](const std::string& op) -> int {
        if (reg8.count(op)) return *reg8[op];
        if (reg16.count(op)) return *reg16[op];
        return parseImmediate(op);
    };

    int value = parseOperand(src);

    if (reg8.count(dest)) {
        *reg8[dest] = static_cast<unsigned char>(value);
    }
    else if (reg16.count(dest)) {
        *reg16[dest] = static_cast<unsigned short>(value);
    }
}

// add指令处理函数
void AddInstruction(const std::string& line) {
    std::string processedLine = line;
    std::replace(processedLine.begin(), processedLine.end(), ',', ' ');
    std::istringstream iss(processedLine);
    std::string opcode, dest, src;
    iss >> opcode >> dest >> src;

    auto& reg8 = createRegister8BitMap();
    auto& reg16 = createRegister16BitMap();

    auto parseOperand = [&](const std::string& op) -> int {
        if (reg8.count(op)) return *reg8[op];
        if (reg16.count(op)) return *reg16[op];
        return parseImmediate(op);
    };

    int val1 = parseOperand(dest);
    int val2 = parseOperand(src);
    int result = val1 + val2;

    if (reg8.count(dest)) {
        *reg8[dest] = static_cast<unsigned char>(result);
    }
    else if (reg16.count(dest)) {
        *reg16[dest] = static_cast<unsigned short>(result);
    }

    ZF = (result == 0);
    SF = (result < 0);
    CF = (static_cast<unsigned>(result) < static_cast<unsigned>(val1));
}

// sub指令处理函数
void SubInstruction(const std::string& line) {
    std::string processedLine = line;
    std::replace(processedLine.begin(), processedLine.end(), ',', ' ');
    std::istringstream iss(processedLine);
    std::string opcode, dest, src;
    iss >> opcode >> dest >> src;

    auto& reg8 = createRegister8BitMap();
    auto& reg16 = createRegister16BitMap();

    auto parseOperand = [&](const std::string& op) -> int {
        if (reg8.count(op)) return *reg8[op];
        if (reg16.count(op)) return *reg16[op];
        return parseImmediate(op);
    };

    int val1 = parseOperand(dest);
    int val2 = parseOperand(src);
    int result = val1 - val2;

    if (reg8.count(dest)) {
        *reg8[dest] = static_cast<unsigned char>(result);
    }
    else if (reg16.count(dest)) {
        *reg16[dest] = static_cast<unsigned short>(result);
    }

    ZF = (result == 0);
    SF = (result < 0);
    CF = (static_cast<unsigned>(val1) < static_cast<unsigned>(val2));
}

// inc指令处理函数
void IncInstruction(const std::string& line) {
    std::istringstream iss(line);
    std::string opcode, operand;
    iss >> opcode >> operand;

    auto& reg8 = createRegister8BitMap();
    auto& reg16 = createRegister16BitMap();

    if (reg8.count(operand)) {
        *reg8[operand] += 1;
        ZF = (*reg8[operand] == 0);
        SF = (*reg8[operand] < 0);
    }
    else if (reg16.count(operand)) {
        *reg16[operand] += 1;
        ZF = (*reg16[operand] == 0);
        SF = (*reg16[operand] < 0);
    }
}

void CmpInstruction(const std::string& line) {
    std::string processedLine = line;
    std::replace(processedLine.begin(), processedLine.end(), ',', ' ');
    std::istringstream iss(processedLine);
    std::string opcode, op1, op2;
    iss >> opcode >> op1 >> op2;

    auto& reg8 = createRegister8BitMap();
    auto& reg16 = createRegister16BitMap();

    auto parseOperand = [&](const std::string& op) -> int {
        if (reg8.count(op)) return *reg8[op];
        if (reg16.count(op)) return *reg16[op];
        return parseImmediate(op);
    };

    int val1 = parseOperand(op1);
    int val2 = parseOperand(op2);
    int result = val1 - val2;

    ZF = (result == 0);
    SF = (result < 0);
    CF = (static_cast<unsigned>(val1) < static_cast<unsigned>(val2));
}

void JmpInstruction(const std::string& line) {
    std::istringstream iss(line);
    std::string opcode, label;
    iss >> opcode >> label;
    if (labels.count(label)) {
        new_current_line = labels[label];
    } else {
        printError(InstructionError::LABEL_NOT_FOUND, "JMP指令中的标签: " + label);
    }
}

void JeInstruction(const std::string& line) {
    std::istringstream iss(line);
    std::string opcode, label;
    iss >> opcode >> label;
    if (ZF) {
        if (labels.count(label)) {
            new_current_line = labels[label];
        } else {
            printError(InstructionError::LABEL_NOT_FOUND, "JE指令中的标签: " + label);
        }
    } else {
        new_current_line = current_line + 1;
    }
}

void JneInstruction(const std::string& line) {
    std::istringstream iss(line);
    std::string opcode, label;
    iss >> opcode >> label;
    if (!ZF) {
        if (labels.count(label)) {
            new_current_line = labels[label];
        } else {
            printError(InstructionError::LABEL_NOT_FOUND, "JNE指令中的标签: " + label);
        }
    } else {
        new_current_line = current_line + 1;
    }
}

void PushInstruction(const std::string& line) {
    std::istringstream iss(line);
    std::string opcode, src;
    iss >> opcode >> src;

    auto& reg16 = createRegister16BitMap();
    unsigned short value = reg16.count(src)? *reg16[src] : parseImmediate(src);

    sp -= 2;
    memory[sp] = value & 0xFF;
    memory[sp + 1] = (value >> 8) & 0xFF;
}

void PopInstruction(const std::string& line) {
    std::istringstream iss(line);
    std::string opcode, dest;
    iss >> opcode >> dest;

    auto& reg16 = createRegister16BitMap();
    if (reg16.count(dest)) {
        *reg16[dest] = memory[sp] | (memory[sp + 1] << 8);
        sp += 2;
    }
}

void XorInstruction(const std::string& line) {
    std::string processedLine = line;
    std::replace(processedLine.begin(), processedLine.end(), ',', ' ');
    std::istringstream iss(processedLine);
    std::string opcode, dest, src;
    iss >> opcode >> dest >> src;

    auto& reg8 = createRegister8BitMap();
    auto& reg16 = createRegister16BitMap();

    auto parseOperand = [&](const s
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值