📄 wasm.cpp
字号:
#include "WASM.h"
#include <iostream>
#include <fstream>
#include <list>
#include <string.h>
using namespace std;
/*
struct Symbol,一个标号
*/
struct Symbol
{
char *name;
unsigned long value;
};
/*
struct Instruction,一条指令
若type=LABEL,op1为标号字符串地址
*/
struct Instruction
{
int type;
unsigned long code;
unsigned long op1, op2, op3;
};
/*
struct Param,字符串形式的指令各参数
*/
struct Param
{
int type; //0-空,1-普通,2-标号
int ops; //操作数数目
char code[256]; //op
char op1[256], op2[256], op3[256];
};
/*
显示软件版本等信息
*/
void showInfo(void);
/*
根据错误码显示错误原因
*/
void showError(int err);
/*
完成汇编
*/
int assemble(char *src, char *dst);
/*
firstLoop,记录标号
*/
int firstLoop(ifstream *pIn, list<Symbol> &symbols);
/*
secondLoop,完成输出
*/
int secondLoop(ifstream *pIn, ofstream *pOut, list<Symbol> &symbols);
/*
分离出指令各参数(字符串形式)
*/
int getParam(char *str, Param *param);
/*
将指令op字符串转换为代码
*/
int insEncode(char *str, unsigned long *pCode, int *type);
/*
将寄存器字符串转换为代码
*/
int regEncode(char *str, unsigned long *pCode);
/*
将立即数和标号字符串转换为代码
*/
int numEncode(char *str, unsigned long *value, list<Symbol> &symbols);
/*
是否为伪指令,返回指令总长度
*/
int isMacro(char *str);
int errLine; //出错行号
void main(int argc, char**argv)
{
errLine = 0;
char srcFilename[1024],dstFilename[1024];
if(argc<=1)
{
showInfo();
return;
}
strcpy(srcFilename,argv[1]);
if(argc>=3)
{
strcpy(dstFilename,argv[2]);
}
else
{
strcpy(dstFilename,srcFilename);
char *ext;
ext = strrchr(dstFilename,'.'); //加扩展名
if(!ext || stricmp(ext, ".asm")&&stricmp(ext, ".txt") )
{
int len = strlen(dstFilename);
ext = dstFilename+len;
}
ext[0] = '.';
ext[1] = 'w';
ext[2] = 0;
}
int err;
err = assemble(srcFilename, dstFilename);
if(!err)
{
cout << "Assembling succeeded." << endl;
showInfo();
}
else
{
cout << "Assembling failed." << endl;
cout << endl;
if(errLine!=0)
cout << "line(" << errLine <<")" << endl; //出错行号
showError(err); //出错原因
cout << endl;
showInfo();
}
}
void showInfo(void)
{
cout << endl;
cout << "Wisp CPU Assembler 1.0 - by Quifi - Dec.2005" << endl;
}
void showError(int err)
{
switch(err)
{
case SOURCE_FILE_CANNOT_BE_OPENED:
cout << "Source file cannot be opened";
break;
case DESTINED_FILE_CANNOT_BE_WRITEN:
cout << "Destined file cannot be written";
break;
case UNDEFINED_INSTRUCTION:
cout << "Undefined instruction";
break;
case UNDEFINED_REGISTER:
cout << "Undefined register";
break;
case UNDEFINED_SYMBOL:
cout << "Undefined symbol";
break;
case SYMBOL_REDEFINED:
cout << "Symbol redefined";
break;
case BAD_FORMAT:
cout << "Bad format";
break;
case IMM_OUT_OF_RANGE:
cout << "Immediate is out of range";
break;
case ADDRESS_NOT_ALIGN:
cout << "Address is not align to 4 bytes";
break;
default:
cout << "Error";
}
}
int assemble(char *src, char *dst)
{
int err;
ifstream in1, in2;
ofstream out;
in1.open(src);
if(!in1.is_open())
{
return SOURCE_FILE_CANNOT_BE_OPENED;
}
list<Symbol> symbols;
err = firstLoop(&in1,symbols);
in1.close();
if(err)
{
return err;
}
in2.open(src);
if(!in2.is_open())
{
return SOURCE_FILE_CANNOT_BE_OPENED;
}
out.open(dst, ios::binary);
if(!out.is_open())
{
return DESTINED_FILE_CANNOT_BE_WRITEN;
}
err = secondLoop(&in2, &out, symbols);
list<Symbol>::iterator it;
for(it=symbols.begin(); it!=symbols.end(); ++it)
{
delete[] (*it).name;
}
in2.close();
out.close();
return err;
}
int firstLoop(ifstream *pIn, list<Symbol> &symbols)
{
errLine=0; //出错行号归零
unsigned long ip;
int err;
Param param;
char line[1024];
Symbol sym;
ip = 0;
while(pIn->getline(line, 1024))
{
++errLine;
err = getParam(line,¶m);
if(err) return err; //错误
if(param.type == EMPTY) //空行
{
continue;
}
if(param.type == LABEL) //标号
{
list<Symbol>::iterator it;
for(it=symbols.begin(); it!=symbols.end(); ++it)
{
if(!stricmp((char *)param.code, it->name))
return SYMBOL_REDEFINED;
}
sym.name = new char[strlen((char *)param.code)+1];
strcpy(sym.name, (char *)param.code);
sym.value = ip;
symbols.push_back(sym);
continue;
}
if(param.type == MACRO) //伪指令
{
ip += param.ops; //param.ops为指令总长
continue;
}
ip += 4; //普通指令或数据
}
return 0; //成功
}
int secondLoop(ifstream *pIn, ofstream *pOut, list<Symbol> &symbols)
{
errLine = 0;
unsigned long ipn;
int err;
bool imm; //是否立即数
Instruction ins;
Param param;
unsigned long dwIns;
char line[1024];
ipn = 0;
while(pIn->getline(line, 1024))
{
++errLine;
err = getParam(line, ¶m);
if(err) return err; //错误
if(param.type==LABEL || param.type==EMPTY)
{
continue;
}
if(param.type==DATA)
{
numEncode(param.op1, &ins.op1, symbols);
dwIns = ins.op1;
pOut->write((char*)&dwIns, 4);
ipn += 4;
continue;
}
if(param.type == MACRO) //伪指令
{
if(!stricmp(param.code,"INIT")) //载入32位立即数(不使用其他寄存器)
{
err = regEncode(param.op1, &ins.op1);
if(err) return err;
err = numEncode(param.op2, &ins.op2, symbols);
if(err) return err;
unsigned long imm16;
//31:16
imm16 = (ins.op2 & 0xffff0000)>>16;
ins.code = 0x1c;
dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op1<<(32-6-5-5))
+ ( imm16 ); //LDA rx, imm[31:16]
pOut->write((char*)&dwIns, 4);
//15:0
imm16 = ins.op2 & 0xffff;
ins.code = 0x1d;
dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op1<<(32-6-5-5))
+ ( imm16 ); //LDA32 rx, imm[15:0]
pOut->write((char*)&dwIns, 4);
ipn += 8;
continue;
}
}
err = insEncode(param.code, &ins.code, &ins.type);
if(err) return err; //错误
if(ins.type == NOP) //空操作
{
dwIns = 0;
}
else if(ins.type == MUL) //乘法
{
err = regEncode(param.op1, &ins.op1);
if(err) return err;
err = regEncode(param.op2, &ins.op2);
if(err) return err;
err = regEncode(param.op3, &ins.op3);
if(err) return err;
dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op2<<(32-6-5-5))
+ (ins.op3<<(32-6-5-5-5));
}
else if(ins.type == ADD) //三操作数ALU运算
{
err = regEncode(param.op1, &ins.op1);
if(err) return err;
err = regEncode(param.op2, &ins.op2);
if(err) return err;
if( regEncode(param.op3, &ins.op3) ) //若第三个操作数不是寄存器
{
err = numEncode(param.op3, &ins.op3, symbols);
if(err) return err;
imm = true;
}
else imm = false;
if(imm) //立即数
{
if(ins.op2 & 0xffff0000 && ~ins.op2 & 0xffff8000)
return IMM_OUT_OF_RANGE;
dwIns = ((ins.code|0x10)<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op2<<(32-6-5-5))
+ (ins.op3 & 0xffff);
}
else //寄存器
{
dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op2<<(32-6-5-5))
+ (ins.op3<<(32-6-5-5-5));
}
}
else if(ins.type == NOT) //NOT
{
err = regEncode(param.op1, &ins.op1);
if(err) return err;
if( regEncode(param.op2, &ins.op2) ) //若第二个操作数不是寄存器
{
err = numEncode(param.op2, &ins.op2, symbols);
if(err) return err;
imm = true;
}
else imm = false;
if(imm) //立即数
{
if(ins.op2 & 0xffff0000 && ~ins.op2 & 0xffff8000)
return IMM_OUT_OF_RANGE;
dwIns = ((ins.code|0x10)<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op2 & 0xffff);
}
else //寄存器
{
dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op2<<(32-6-5-5-5));
}
}
else if(ins.type == CMP) //CMP&TST
{
err = regEncode(param.op1, &ins.op1);
if(err) return err;
if( regEncode(param.op2, &ins.op2) ) //若第二个操作数不是寄存器
{
err = numEncode(param.op2, &ins.op2, symbols);
if(err) return err;
imm = true;
}
else imm = false;
if(imm) //立即数
{
if(ins.op2 & 0xffff0000 && ~ins.op2 & 0xffff8000)
return IMM_OUT_OF_RANGE;
dwIns = ((ins.code|0x10)<<(32-6)) + (ins.op1<<(32-6-5-5)) + (ins.op2 & 0xffff);
}
else //寄存器
{
dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5-5)) + (ins.op2<<(32-6-5-5-5));
}
}
else if(ins.type == MOV) //MOV
{
err = regEncode(param.op1, &ins.op1);
if(err) return err;
err = regEncode(param.op2, &ins.op2);
if(err) return err;
dwIns = (ins.code<<(32-6)) + (ins.op1<<(32-6-5)) + (ins.op2<<(32-6-5-5-5));
}
else if(ins.type == JMP) //JMP imm26/REG
{
if( regEncode(param.op1, &ins.op1) ) //若操作数不是寄存器
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -