OTL终于能写出点实用的东西了。今天写的一个MIPS汇编器,能读入若干行MIPS指令,将其翻译成机器码,存入一个文本文件中。目前只能编译add, sub, and, or, slt, beq, j, lw, sw, nop这几种指令,并且不能识别注释。不过对于完成计算机组成实验来说足够了。
// A simple and naive MIPS assembler
// Use this command to make: g++ MIPS.cpp -o MIPS
// Usage: ./MIPS CodeFile
#include<iostream>
#include<stdio.h>
#include<memory.h>
#include<cstring>
#include<fstream>
#include<iomanip>
#include<cstdlib>
using namespace std;
// A function used to extract the register number from string "$xx"
int getReg(char* arg){
int reg = 0;
char *p = arg;
while (*p == ' ') p++; // Skip the space at the beginning
if (*p == '$') p++;
else return -1; // Unexpected charaters
// Parse
while(*p >= '0' && *p <= '9'){
reg = 10 * reg + (*p - '0');
p++;
}
while (*p == ' ') p++; // Skip the space following the number
if (*p != '\0') return -1; // Unexpected characters
else return reg;
}
// Output a binary number with a given length to an object of ostream
void printBin(int num, int digi, ostream& os){
char *bin = new char[digi];
memset(bin, '0', digi * sizeof(char));
char *p = bin + (strlen(bin) - 1);
int sign = (num >= 0)? 1: -1;
num = num * sign;
while (num > 0){
if (num & 1) *p = '1';
num >>= 1;
p--;
}
// Transform to the 2's complement
if (sign == -1){
p = bin + (strlen(bin) - 1);
while (p >= bin && *p != '1') p--; // Find the last '1'
if (p >= bin && *p == '1') p--; // Skip the last '1'
while (p >= bin) {
*p = ('0' + '1') - *p;
p--;
}
}
os << bin;
delete bin;
}
int main(int argc, char** argv){
// Check the input
if (argc != 2){
cout << "Error: File name needed." << endl;
exit(-1);
}
ifstream code(argv[1]);
char *objname = new char[strlen(argv[1]) + 10];
strcpy(objname, argv[1]);
int i;
// Find the suffix
for (i = strlen(objname) - 1; i >= 0; i--) if (objname[i] == '.') break;
// Give the output file a ".mips" suffix
if (objname[i] == '.'){
objname[i + 1] = '\0';
strcat(objname, "mips");
}
else strcat(objname, ".mips");
ofstream obj(objname);
delete objname;
/****************************************************
The instruction strctures
R-type:
+------------------------------------------------+
| opcode | rs | rt | rd | shamt | funct |
|--------+-------+-------+-------+-------+-------|
| 6-bit | 5-bit | 5-bit | 5-bit | 5-bit | 6-bit |
+------------------------------------------------+
I-type:
+------------------------------------------------+
| opcode | rs | rt | immediate |
|--------+-------+-------+-----------------------|
| 6-bit | 5-bit | 5-bit | 16-bit |
+------------------------------------------------+