c++ write シンプルなmipsコンパイラ
グループ実験を書くときには、まずmips文をバイナリ・マシンコードに変換する必要があるので、バイナリ・マシンコードはコンパイラの力を借りずに、コード表に対して一つ一つ手作業でコンパイルするしかない。気をつけないと間違うし、間違ったら間違いを見つけるのが大変で、再コンパイルが必要になることもあります。
そこで、32ビット長のバイナリ・マシン・コードに必要な基本的なmips文をコンパイルできる簡単なmipsコンパイラをc++で実装することにしたのです。
まず、別のブログ(Multi-cycle cpu design and implementation)で紹介したmips命令を使って、以下のようにテキストファイルtxtの中にmips命令を記述する必要があります。
この後、c++ファイルにmips命令を読み込んで、文字列を解析してデコードする必要があります。
int main() {
int binary[32][32];
ifstream fin;
fin.open("mips.txt", ios_base::in);
if(!fin) {
cerr << "Open Error!" << endl;
exit(1);
}
int i, j;
char buffer[256];
char* q = NULL;
char* op;
string oop;
for(i = 0; i < 32; i++) {
for(j = 0; j < 32; j++) {
binary[i][j] = 0;
}
}
j = 0;
while(!fin.eof()) {
fin.getline(buffer, 100);
if(buffer[0] ! = 0) {
q = NULL;
op = strtok(buffer, ", $(), () ");
oop = op;
int* newline = fromooptobinary(oop);
for(i = 0; i < 32; i++) {
binary[j][i] = newline[i];
}
}
j++;
}
int count = j;
string tolower(string s) {
int len = s.size();
for (int i=0; i<len; i++) {
if ( s[i] >= 'A' && s[i] <= 'Z' ) {
s[i] += ('a' - 'A' ) ;
}
}
return s;
}
int* chartobinary(char *p) {
int i = 0;
int j = -1;
int k = 0;
int *q = new int[32];
for (i = 3; i < 10; i++) {
int a = p[i] - '0';
j += 4;
for(k = 0; k < 4; k++) {
q[j] = a%2;
a = a/2;
j--;
}
j += 4;
}
return q;
}
用途は int* fromooptobinary (string oop) 関数です。
if(oop == "j" || oop == "jal") {
binary[0] = binary[1] = binary[2] = 1;
if(oop == "jal") binary[4] = 1;
p = strtok(NULL, ", $(), () ");
int *k = chartobinary(p);
for(i = 6; i < 32; i++) {
binary[i] = k[i-6];
}
}
次に、レジスタ番号を5ビットのバイナリ・マシン・コード、または16ビットのバイナリ・マシン・コードに変換する必要があるデコードがあり、カスタム関数があります。
int* inttobinary(int t, bool choose) {
int i = 0;
if(choose) {
int* q = new int[5];
for(i = 4; i >= 0; i--) {
q[i] = t%2;
t = t/2;
}
return q;
} else {
bool check = false;
if(t<0) {
check = true;
t = -t;
}
int* p = new int[16];
for(i = 15; i >= 0; i--) {
p[i] = t%2;
t = t/2;
}
if(check) {
for(i = 15; i >= 0; i--) {
if(p[i] == 0) p[i] = 1;
else p[i] = 0;
}
int j = 15;
while(p[j] ! = 0) {
p[j] = 0;
j--;
}
if(j>=0&&p[j]==0) {
p[j] = 1;
}
}
return p;
}
}
この関数の使用は、例えば int* fromooptobinary (string oop) 関数の中にも見られます。
else if(oop == "move") {
binary[0] = 1;
p = strtok(NULL, ", $(), () ");
int k = atoi(p);
int* newline = inttobinary(k, true);
p = strtok(NULL, ", $(), () ");
k = atoi(p);
int* newline2 = inttobinary(k, true);
for(i = 6; i < 11; i++) {
binary[i] = newline2[i-6];
binary[i+10] = newline[i-6];
}
}
この時点で基本的にデコードは完了しているので、次にやるべきことはバイナリ配列を別のテキストファイルに書き出すことだけです。
/*write to txt*/
ofstream out;
out.open("data.txt", ios::out|ios::trunc);
if(out.is_open()) {
for(i = 0; i < count; i++) {
for(j = 0; j < 32; j++) {
out << binary[i][j];
if((j+1)%8 == 0 && j!=31) {
out << " ";
}
}
if(i ! = count - 1) {
out << "\n";
}
}
cout << "compile success!" <<endl;
out.close();
}
ios::truncは、最初に内容をクリアしてファイルを開くことを意味します。
c++ のファイル読み書きの具体的な方法は、http://blog.csdn.net/zhongzi_l/article/details/51541351 を参照してください。
このように、単純なmipsコンパイラが嬉しいことに完成したわけですが、もちろん、入力が基本入力フォーマットに沿っていない場合、デコードに予測できないエラーが発生する可能性があるなど、不完全な点も多々あります。
ここでは、その集計結果を見てみましょう。
この結果は、マルチサイクルCPUの設計・実装における値と整合しています。コンパイルは成功しました。
次に、この自作簡易mipsコンパイラを使って、他のブログ(シングルサイクルCPUの設計と実装)のmips命令も、もちろん少し手を加えてコンパイルしてみましたが、結果は正しく、このようになりました。
今回、簡単なmipsコンパイラを作る過程はかなり大変でしたが、全体的には自分の中で満足度が高く、この後もっと強力なコンパイラを作りたいと考えています。
関連
-
[解決済み】エラー。"イニシャライザー式リストが複合式として扱われる"
-
[解決済み】 ベクターの重複を消去してソートする最も効率的な方法は何ですか?
-
[解決済み] rhsの仕組みについて教えてください。
-
[解決済み] C++の戻り値が-858993460と表示される。
-
[解決済み] 既存のテキストファイルの上書き c++
-
[解決済み] C2678 二項演算子 '<': 左側のオペランドが 'const Node' 型である演算子が見つかりません (または、受け入れ可能な変換がありません) [重複] 。
-
[解決済み] malloc() : メモリ破壊 (高速) c++
-
[解決済み] 無効なNullポインタ - C++
-
[解決済み] エラー: 異なる型での typedef 再定義
-
[解決済み] ランダムなブール値を生成する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C++ クラスヘッダが含まれているときに「不明な型」があるのはなぜですか?重複
-
[解決済み】c++でstd::vectorを返すための効率的な方法
-
[解決済み] 変数サイズのオブジェクトが初期化されないことがある c++
-
[解決済み】libstdc++-6.dllが見つからない。
-
[解決済み】静的リンクのあるメンバー関数
-
[解決済み】size_tをdoubleまたはintにキャストする方法 C++
-
[解決済み] VC++の致命的なエラー LNK1168: 書き込みのために filename.exe を開くことができない
-
[解決済み] UNREFERENCED_PARAMETER マクロの使用
-
[解決済み] makefile のエラー: main への未定義の参照
-
c++のコンストラクタが非クラス型であるオッドボール問題