通过创建32位虚拟机的思想解决问题
2026-04-18 17:57:22
发布于:浙江
***飞逝的的时光不会模糊我对你的记忆。难以相信从我第一次见到你以来已经过去了 3 年。我仍然还生动地记得,3 年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀着你玫瑰色的脸颊。我明白,我已经沉醉于你了。之后,经过几个月的观察和窥探,你的优雅与智慧,你对待生活的态度和你对未来的愿望深切地在我心中留下了印象。你是迷人的阳光女孩,我总是梦想着与你分享余生。唉,实际上你远远超过了我最疯狂的梦想。我不知道如何桥起我与你之间的鸿沟。所以我没有任何计划,仅仅只是等待,等待一个适当的机会到来。直到现在,毕业的到来,我意识到我是个傻瓜,我应该创造机会并且抓住它而不只是等待。
这些日子里,我和我的朋友、室友、同学一个接一个地分开。我仍无法相信,在挥手之后,这些熟悉的面孔很快就会从我们的生活中消失,仅仅留下回忆。我明天就将离开学校。你已经计划远走高飞,追求你的未来,实现你的梦想。如果没有命运,也许我们不会再次相遇。所以今晚,我正在你的宿舍楼下徘徊,希望能偶然遇见你。但矛盾的是,你的美貌一定会使我心跳加速,我笨拙的舌头也许无法吐出一个字。我不记得我曾多少次经过你的宿舍楼,每次都希望看到你出现在阳台上或是窗台上。我不记得这个想法曾多少次在我的脑海中涌出:打电话叫她一起吃晚饭或是聊聊天。但每次,考虑到你的优秀和我的平凡,胆怯的优势超越勇气驱使我静静地离开。
毕业,意味着中学生活的终结。这些光荣与浪漫的时代结束。你可爱的微笑是我原来努力学习的动力,这单相思的爱情会被密封,作为一个我心灵深处的记忆。毕业,也意味着新生活的开始,一个到达光明未来的足迹。我真希望你在国外天天开心,一切顺利。同时,我将努力从幼稚中走出来,变得更加成熟。我的理想将是在现实中追求我的爱与幸福,我永远不会放弃。
再见了,我的公主!
如果有一天,在某个天涯海角,我们有机会相聚,即使是白发苍苍的男人和女人,在那个时候,我希望我们可以成为好朋友来自豪地分享这个记忆,重温年轻快乐的激情。如果这个机会永远没有到来,我希望我是天空中的星星,在你的窗外闪烁。远远地保佑着你,就像一个朋友,每天晚上陪伴在你左右,一同分享甜美的梦亦或是一同经历可怕的梦。***
首先我们看到题目,就知道这道题并不简单,我们为了提高代码的可读性,所以选用创建虚拟机的方式来解决题目。这样可以提高可读性
-
首先对于数据大小来看,32位是必须的
下面上代码:
#include <cstdint>
#include <vector>
#include <array>
#include <iostream>
#include <stdexcept>
class VM32 {
public:
using u32 = uint32_t;
using i32 = int32_t;
enum Registers {
EAX, EBX, ECX, EDX,
ESP, EIP,
REG_COUNT
};
enum OpCode : u32 {
HALT = 0x00000000,
MOV_REG = 0x01000000,
MOV_MEM = 0x02000000,
MOV_IMM = 0x03000000,
ADD_REG = 0x04000000,
SUB_REG = 0x05000000,
MUL_REG = 0x06000000,
DIV_REG = 0x07000000,
PUSH = 0x08000000,
POP = 0x09000000,
JMP = 0x0A000000,
IN = 0x0B000000,
OUT = 0x0C000000,
STR_MEM = 0x0D000000,
LDR_MEM = 0x0E000000
};
static constexpr size_t MEM_SIZE = 16 * 1024 * 1024;
VM32() {
registers.fill(0);
registers[ESP] = MEM_SIZE - 4;
memory.resize(MEM_SIZE, 0);
}
void load_program(const std::vector<u32>& program, size_t size) {
if (size > memory.size()) {
throw std::runtime_error("Program too large");
}
for (size_t i = 0; i < size; ++i) {
memory[i] = program[i];
}
}
void run() {
while (true) {
u32 eip = registers[EIP];
if (eip >= memory.size()) {
throw std::runtime_error("EIP out of bounds");
}
u32 instruction = memory[eip];
registers[EIP] += 1;
u32 op = instruction & 0xFF000000;
u32 args = instruction & 0x00FFFFFF;
switch (op) {
case HALT:
return;
case MOV_REG: {
u32 src_reg = (args >> 16) & 0xFF;
u32 dst_reg = args & 0xFF;
if (src_reg >= REG_COUNT || dst_reg >= REG_COUNT) {
throw std::runtime_error("Invalid reg");
}
registers[dst_reg] = registers[src_reg];
break;
}
case MOV_IMM: {
u32 dst_reg = args & 0xFF;
if (dst_reg >= REG_COUNT) {
throw std::runtime_error("Invalid reg");
}
u32 imm = memory[registers[EIP]];
registers[EIP] += 1;
registers[dst_reg] = imm;
break;
}
case ADD_REG: {
u32 src_reg = (args >> 16) & 0xFF;
u32 dst_reg = args & 0xFF;
if (src_reg >= REG_COUNT || dst_reg >= REG_COUNT) {
throw std::runtime_error("Invalid reg");
}
registers[dst_reg] += registers[src_reg];
break;
}
case SUB_REG: {
u32 src_reg = (args >> 16) & 0xFF;
u32 dst_reg = args & 0xFF;
if (src_reg >= REG_COUNT || dst_reg >= REG_COUNT) {
throw std::runtime_error("Invalid reg");
}
registers[dst_reg] -= registers[src_reg];
break;
}
case MUL_REG: {
u32 src_reg = (args >> 16) & 0xFF;
u32 dst_reg = args & 0xFF;
if (src_reg >= REG_COUNT || dst_reg >= REG_COUNT) {
throw std::runtime_error("Invalid reg");
}
registers[dst_reg] *= registers[src_reg];
break;
}
case DIV_REG: {
u32 src_reg = (args >> 16) & 0xFF;
u32 dst_reg = args & 0xFF;
if (src_reg >= REG_COUNT || dst_reg >= REG_COUNT) {
throw std::runtime_error("Invalid reg");
}
if (registers[src_reg] == 0) {
throw std::runtime_error("Divide by zero");
}
registers[dst_reg] /= registers[src_reg];
break;
}
case PUSH: {
u32 reg = args & 0xFF;
if (reg >= REG_COUNT) {
throw std::runtime_error("Invalid reg");
}
registers[ESP] -= 4;
memory[registers[ESP]] = registers[reg];
break;
}
case POP: {
u32 reg = args & 0xFF;
if (reg >= REG_COUNT) {
throw std::runtime_error("Invalid reg");
}
registers[reg] = memory[registers[ESP]];
registers[ESP] += 4;
break;
}
case JMP: {
u32 target_addr = memory[registers[EIP]];
registers[EIP] = target_addr;
break;
}
case IN: {
u32 dst_reg = args & 0xFF;
if (dst_reg >= REG_COUNT) {
throw std::runtime_error("Invalid reg");
}
u32 input_val;
std::cin >> input_val;
registers[dst_reg] = input_val;
break;
}
case OUT: {
u32 src_reg = args & 0xFF;
if (src_reg >= REG_COUNT) {
throw std::runtime_error("Invalid reg");
}
std::cout << registers[src_reg] << std::endl;
break;
}
case STR_MEM: {
u32 src_reg = (args >> 16) & 0xFF;
if (src_reg >= REG_COUNT) {
throw std::runtime_error("Invalid reg");
}
u32 mem_addr = memory[registers[EIP]];
registers[EIP] += 1;
if (mem_addr >= memory.size()) {
throw std::runtime_error("Mem out of bounds");
}
memory[mem_addr] = registers[src_reg];
break;
}
case LDR_MEM: {
u32 dst_reg = (args >> 16) & 0xFF;
if (dst_reg >= REG_COUNT) {
throw std::runtime_error("Invalid reg");
}
u32 mem_addr = memory[registers[EIP]];
registers[EIP] += 1;
if (mem_addr >= memory.size()) {
throw std::runtime_error("Mem out of bounds");
}
registers[dst_reg] = memory[mem_addr];
break;
}
default:
throw std::runtime_error("Invalid opcode: " + std::to_string(op));
}
}
}
private:
std::array<u32, REG_COUNT> registers;
std::vector<u32> memory;
};
int main() {
try {
VM32 vm;
std::vector<VM32::u32> program = {
0x0B000000 | VM32::EAX,
0x0B000000 | VM32::EBX,
0x04000000 | (VM32::EBX << 16) | VM32::EAX,
0x0C000000 | VM32::EAX,
0x00000000
};
vm.load_program(program, 5);
vm.run();
} catch (const std::exception& e) {
std::cerr << "虚拟机错误:" << e.what() << std::endl;
return 1;
}
return 0;
}
可以AC:

也就是内存消耗高一点
全部评论 4
顶
1周前 来自 浙江
0顶
1周前 来自 浙江
0顶
1周前 来自 浙江
0有点意思
1周前 来自 浙江
0



有帮助,赞一个