动手写riscv emulator(一)

CPU是计算机中最重要的核心部件之一。模拟器除了要模拟CPU之外,还需要模拟其他的部件,才能够让模拟器运行起来,例如:dram、bus等等。这个章节我们要完成以下两个目标:

  1. 先把模拟器的代码结构和编译搭建起来

  2. 能够把可执行文件转换成二进制文件,并读取二进制文件内容

本文使用的是vscode + gcc + gdb进行编译和调试,其中使用vscode + gdb在vscode上进行断点调试。编译使用的是CMake + gcc的方式。vscode + gdb进行调试需要配置vscode,可以参考gdb远程调试 - cockpunctual - 博客园只需要参考该博客的第二个小节配置vscode

使用C++面向对象的思想来写这个CPU模拟器。

1 类定义

定义一个CPU类,负责指定代码:

class CPU {
    public:
        CPU(std::vector<char>& code);
        void decode();
    private:
        std::vector<uint64_t> int_reg;
        std::vector<char> code;
        uint64_t pc;
        uint64_t csrs;
};

decode函数是负责解析指令的,本章节还不涉及,暂时把读取到的指令输出出来:

CPU::CPU(std::vector<char>& code)
{
    this->code = code;
}

void CPU::decode()
{
    for(char instruction : this->code) {
        printf("0x%x\n", (unsigned char)instruction);
    }
}

2 读取文件

这里要解决的是前面提到的第二个目标。我们的测试用例是把下面的汇编代码转换成二进制文件读取出来:

addi x29, x0, 5
addi x30, x0, 37
add x31, x30, x29

上面的测试用例放在test/add/addi.s。我们需要对上面的汇编代码进行转换:

riscv64-unknown-linux-gnu-gcc -Wl,-Ttext=0x80000000 -nostdlib -o addi.elf addi.s
riscv64-unknown-linux-gnu-objcopy -O binary addi.elf addi.bin

上面的命令:

  1. 把addi.s文件编译成elf文件

  2. 把elf文件中指令部分拷贝出来存放到addi.bin文件中

编译完bin文件后,我们接下来的操作就是要把二进制文件内容读取出来,为后续的章节做好铺垫。

std::vector<char> read_file(const std::string path)
{
    std::vector<char> buf;
    std::streampos file_size;
    std::ifstream file(path, std::ios::in | std::ios::binary);
    if (!file.is_open()) {
        std::cout << path << " is not opened." << std::endl;
        return buf;
    }

    file.seekg(0, std::ios::end);
    file_size = file.tellg();
    file.seekg(0, std::ios::beg);

    buf.resize(file_size);

    file.read(buf.data(), file_size);
    file.close();
    return buf;
}

3 测试

我们在main函数中定义CPU对象,并且读取bin文件,对bin文件内容进行打印:

int main()
{
    std::cout << "riscv emu" << std::endl;
    std::vector<char> code = read_file("../test/add/addi.bin");
    CPU riscv_cpu(code);
    riscv_cpu.decode();
    return 0;
}

到这里第一章节的内容就完成了,后续我们需要继续添加其他的部件(如dram、bus等)。

posted @ 2026-01-23 17:27  cockpunctual  阅读(0)  评论(0)    收藏  举报