みけCATのにっき(仮)
つれづれなるまゝに、日くらし、PCにむかひて、心に移りゆくよしなし事を、そこはかとなく書きつくれば、あやしうこそものぐるほしけれ。
(本当か!?)
出典

コンパイラを作りたい

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

コンパイラを作りたい

投稿記事 by みけCAT » 11年前

コンパイラとは、ソースコードを機械語に変換するソフトウェアである。

自分も、そんなコンパイラを作ってみたいと思いました。
そこで、まずはアセンブリ言語ではないソースコードをアセンブリ言語のソースコードに変換するプログラムを作りました。

CODE:

#include 

#define STACK_LIMIT 1024

void printStandardLibrary(void) {
	puts(".code16gcc");
	puts("_start:");
	puts("\tmovw $0x1000,%cx");
	puts("\tmovw %cx,%ds");
	puts("\txorw %cx,%cx");
	puts("\txorw %bx,%bx");
	puts("_arrayinit_loop:");
	puts("\tmovb $0,%ds:(%bx)");
	puts("\tincw %bx");
	puts("\tloopw _arrayinit_loop");
	puts("\txorw %si,%si");
	puts("\tjmp _main");

	puts("_input_char:");
	puts("\txorw %ax,%ax");
	puts("\tint $0x16");
	puts("\ttestb %al,%al");
	puts("\tjz _input_char");
	puts("\tmovb %al,%ds:(%si)");
	puts("\tretw");

	puts("_output_char:");
	puts("\tmovb $0x0E,%ah");
	puts("\tmovb %ds:(%si),%al");
	puts("\tmovw $0x0007,%bx");
	puts("\tint $0x10");
	puts("\tretw");

	puts("_main:");
}

int main(void) {
	int input=0;
	int bracketCount=0;
	int stack[STACK_LIMIT]={};
	int stackNum=0;
	printStandardLibrary();
	while((input=getchar())!=EOF) {
		switch(input) {
			case '>':
				puts("\tincw %si");
				break;
			case '=STACK_LIMIT) {
					fputs("error: internal stack overflow (too many \"[\")\n",stderr);
					return 1;
				}
				stack[stackNum++]=bracketCount;
				bracketCount++;
				break;
			case ']':
				if(stackNum0) {
		fputs("error: \"[\" without \"]\" exists\n",stderr);
		return 1;
	}
	puts("_hlt_loop:");
	puts("\thlt");
	puts("\tjmp _hlt_loop");
	return 0;
}
そうです。これはBrainfu*kのソースコードをアセンブリ言語に変換するプログラムです。
標準入力からBrainfu*kのソースコードを入れると、標準出力からアセンブリ言語のプログラムが出てきます。

試しに変換してみましょう。
Wikipediaより、Hello worldプログラム

CODE:

+++++++++[>++++++++>+++++++++++>+++++.>++.+++++++..+++.>-.
------------.+.
(このプログラムはクリエイティブ・コモンズ 表示-継承 3.0 Unportedライセンスの下で利用可能です)

このプログラムでアセンブリ言語に変換すると、こうなりました。
► スポイラーを表示
これをgccで.oファイルに変換し、objdumpで機械語に変換すると、こうなりました。

CODE:

B900108ED931C931DBC6070043E2FA31F6EB1531C0CD1684C074F88804C3B40E
8A04BB0700CD10C3800401800401800401800401800401800401800401800401
8004018A0484C074574680040180040180040180040180040180040180040180
0401468004018004018004018004018004018004018004018004018004018004
01800401468004018004018004018004018004014E4E4E802C018A0484C075A9
46E87AFF46800401800401E870FF800401800401800401800401800401800401
800401E858FFE855FF800401800401800401E849FF46802C01E842FF802C0180
2C01802C01802C01802C01802C01802C01802C01802C01802C01802C01802C01
E81BFF4E800401800401800401800401800401800401800401800401E8FFFE80
2C01802C01802C01802C01802C01802C01802C01802C01E8E4FE800401800401
800401E8D8FE802C01802C01802C01802C01802C01802C01E8C3FE802C01802C
01802C01802C01802C01802C01802C01802C01E8A8FE46800401E8A1FEF4EBFD
これをそのままx86 WebStudioに投げ…たいところですが、このままだと未実装だと怒られてしまいます。
そこで、対症療法として1行目の"E2FA"を"9090"に書き換え、最後の行の"F4"を"90"に書き換えます。
そして書き換えた文字列をx86 WebStudioの入力欄にコピペし、
「ディスプレイ」ボタンで黒い画面を出してから「実行」ボタンを押すと、
きちんと"Hello, world!"と表示されることがわかります。

これでアセンブリ言語ではないソースコードをアセンブリ言語に変換できることがわかったので、
あとはこのプログラムを少し改造し、gccが出力している機械語を真似て直接出力するようにすれば、
「コンパイラ」の完成!となると思います。

naohiro19
記事: 256
登録日時: 14年前

Re: コンパイラを作りたい

投稿記事 by naohiro19 » 11年前

アセンブリ言語のソースがすごいですね

アバター
TOMY
記事: 53
登録日時: 13年前

Re: コンパイラを作りたい

投稿記事 by TOMY » 11年前

うわ、自分ちんぷんかんぷんです・・・情けない・・・