题目描述
小明的汇编语言课程布置了一个大作业,要求设计一种虚拟机解释器,解析并执行以下虚拟指令。虚拟机约定如下:
- 32位的整形寄存器有
a0
到a31
,共32个寄存器。 - 整个虚拟机只有寄存器和立即数参与计算。
- 支持以下指令:
MOV dst src
:将src
的值赋给dst
。ADD dst src0 src1
:将src0
和src1
的和赋给dst
。SUB dst src0 src1
:将src0
和src1
的差赋给dst
。MUL dst src0 src1
:将src0
和src1
的积赋给dst
。DIV dst src0 src1
:将src0
除以src1
的结果(向下取整)赋给dst
。PRINT dst
:打印dst
寄存器的值。
规定:
- 不用考虑计算溢出(用例保证)。
- 指令数最多100条,至少有一条
PRINT
指令。 - 寄存器保证先赋值再引用。
- 不用考虑小数以及除0错误。
输入描述
若干行,每行一条指令。指令格式如下:
MOV dst src
ADD dst src0 src1
SUB dst src0 src1
MUL dst src0 src1
DIV dst src0 src1
PRINT dst
输出描述
对输入的每行指令,若为PRINT
指令,则输出打印一行,该行中包括一个整数,表示寄存器的值。
用例输入
MOV a1 100
MOV a2 200
ADD a3 a1 100
SUB a4 a3 a2
PRINT a4
0
a1=100
a2=200
a3=a1(100)+100=200
a4=a3(200)-a2(200)=0
MOV a1 100
MOV a2 200
PRINT a1
ADD a3 a1 100
SUB a4 a3 a2
PRINT a4
100
0
解题思路
-
数据结构:
- 使用
map<string, int>
存储寄存器的值,键为寄存器名称(如a1
),值为寄存器的整数值。
- 使用
-
指令解析:
- 使用
istringstream
解析每条指令,根据指令类型执行不同的操作。 - 对于
MOV
、ADD
、SUB
、MUL
、DIV
指令,解析目标寄存器和源寄存器/立即数,并执行相应的操作。 - 对于
PRINT
指令,直接输出目标寄存器的值。
- 使用
-
辅助函数:
change(string& src)
:将输入的字符串转换为对应的值,如果是寄存器则返回寄存器的值,如果是立即数则直接转换为整数。
-
除法处理:
- C++的除法是向零取整,而题目要求向下取整,因此需要对除法结果进行特殊处理。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<algorithm>
#include<string>
#include<vector>
#include<unordered_map>
#include<unordered_set>
#include<queue>
#include<set>
#include<list>
#include<sstream>
#include<bitset>
#include<stack>
#include<climits>
#include<iomanip>
#include<cstdint>
using namespace std;
map<string, int> datas;
// 辅助函数:将输入的字符串转换为对应的值
int change(string& src) {
if (src[0] == 'a') return datas[src]; // 如果是寄存器,返回寄存器的值
else return atoi(src.c_str()); // 如果是立即数,直接转换为整数
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string input;
while (getline(cin, input)) {
istringstream is(input);
string cur, dst, src0, src1;
int value;
is >> cur; // 获取指令类型
if (cur == "MOV") {
is >> dst >> value; // 获取目标寄存器和源值
datas[dst] = value; // 执行MOV操作
} else if (cur == "ADD") {
is >> dst >> src0 >> src1; // 获取目标寄存器和两个源值
datas[dst] = change(src0) + change(src1); // 执行ADD操作
} else if (cur == "SUB") {
is >> dst >> src0 >> src1;
datas[dst] = change(src0) - change(src1); // 执行SUB操作
} else if (cur == "MUL") {
is >> dst >> src0 >> src1;
datas[dst] = change(src0) * change(src1); // 执行MUL操作
} else if (cur == "DIV") {
is >> dst >> src0 >> src1;
// C++ 的除法是向零取整,需要处理成向下取整
double temp = (double)change(src0) / (double)change(src1);
datas[dst] = int(floor(temp)); // 执行DIV操作
} else {
is >> dst;
cout << datas[dst] << "\n"; // 执行PRINT操作,输出寄存器的值
}
}
return 0;
}