コンパイラ・課題3

コンパイラ・課題 3
12-09802・j20980
辻 航平
[email protected]
平成 27 年 2 月 20 日
目的
1
ポインタ型を使ったプログラムをコンパイルできるようにする.これによりポインタによる値の
受け渡しが可能となりプログラム本体が冗長とならない.また,ポインタを配列の代わりに使用す
ることで配列の使用が可能となる.
ポインタ型のための拡張
2
2.1
単項演算子のための拡張
今までは各単項演算子が存在していてもその処理を行わず,変数がそのまま右辺値として扱われ
ていた.そこで,各単項演算子に対してその次の変数のスタックへの積み方を変えるようにした.
これにより&がついた変数はそのアドレス,つまり左辺値を,がついたポインタ型変数はその右辺
値であるアドレスをスタックに積むようなアセンブリコードを生成する事ができる.また,がつい
たポインタが右辺に存在していた場合はそのポインタが指す値が必要なので,積まれたアドレスに
格納されている値をスタックに積むアセンブリコードを前処理の直後に生成するようにしている.
単項演算子&が左辺値で見つかった場合は左辺が代入可能な変数ではなくなるので講義資料にのっ
とりコンパイルエラーとしている.
2.2
ポインタ演算のための拡張
アドレスに定数そのままが足し引きされるようになっていたので,ポインタ型であった際はポイ
ンタ演算をするように数行アセンブリコードを追加した.
被加数被減数がポインタ型であった場合に第二引数を 4 倍して計算するアセンブリコードを生成す
るようにした.これによりポインタと定数の計算の際には定数がポインタのサイズとして計算され
るようになった.
ポインタ同士の減算は 2 つのポインタのアドレスをそのまま計算し,その結果をさらに 4 で割った
結果をスタックに積むようなアセンブリコードを生成する事で実現した.
ポインタ同士の加算はプログラムのコンパイル時にエラーとして出力されるため,改めて実装は
しなかった.
1
2.3
ポインタをスタックに積み込むための拡張
今までは読んだポインタに対して何の作業もしていなかったが,大域変数,局所変数,関数引数
に対してその右辺値,左辺値をスタックに積むようなアセンブリコードを生成できるようにした.
これによってポインタ型の変数をスタックに積む事ができる.
実行結果
3
与えられた kadai3.c が正常に動作する事を確認した.
$ ./xcc test/kadai3.c > kadai3.s
$ gcc -m32 kadai3.s
ld: warning: PIE disabled. Absolute addressing ......
$ ./a.out 5
0
1
2
3
4
$ ./a.out 10
1
2
2
3
5
5
5
6
7
9
$
また,以下の自作のプログラムが正常に動作する事を確認した.
2
int printf();
/*int *ptr;*/
/*int data;*/
int main() {
int data;
int *ptr;
data = 5;
printf("整数型の変数 data の値 = %d\n", data);
printf("整数型の変数 data のアドレス = %08X\n", &data);
ptr = &data;
*ptr = 9;
printf("ポインタ型の変数 ptr = %08X\n", ptr);
printf("整数型の変数 data の値 = %d\n", data);
printf("ptr が指す場所に保存されている値 = %d\n", *ptr);
}
$ ./xcc test/test3.c > test3.s
$ gcc -m32 test3.s
ld: warning: PIE disabled. Absolute addressing ......
$ ./a.out
整数型の変数 data の値 = 5
整数型の変数 data のアドレス = BFFFFB74
ポインタ型の変数 ptr = BFFFFB74
整数型の変数 data の値 = 9
ptr が指す場所に保存されている値 = 9
$
以上より正常にコンパイルできていると判断した.
4
評価
int 型のポインタのためのコンパイラは十分に実現できた.
3
5
考察
こういう書き方はあまりしないとは思うが単項演算子のコンパイルの際に&&のような書き方を
するとコンパイルができなくなる.これを避けるには頭と最後の単項演算子を記憶して間の単項演
算子を読み飛ばせばよいと考える.また,そのようにすると最大でも単項演算子 2 つ分のアセンブ
リコードしか生成されず,生成されるアセンブリコードも冗長とならない.
6
まとめ
以上の考え方で int 型ポインタを使ったプログラムをコンパイルできるコンパイラを実現し,確
かに配列として使用していても問題なくコンパイルできる事を確認した.
以上を再実験課題 3 のレポートとする.
参考文献
[1] 情報実験第四「コンパイラ」課題説明資料
4