10/22
自作Cコンパイラは構造体の実装が完了しました。ローカルな構造体変数、グローバルなローカル変数、ネストされた構造体などの仕様に対応しています。面白いことに、ローカルな構造体変数と、グローバルな構造体変数はほとんど実装方法が変わらないということです。「構造体変数名.メンバ名」という字句があるとすると、構造体変数名の部分でグローバル変数とローカル変数のアドレスの指定方法が異なります。しかし後半のメンバ名は先程生成したアドレスからのオフセットでよいので、グローバル変数と、ローカル変数で共通の処理で実装することができます。そのことに気づかず、だいぶ悩みました。
またローカル変数のメモリの割り当て方法に問題がありました。本来は、rbpレジスタからのオフセットを識別子ごとに持たせ、メモリに配置します。しかし私のプログラムでは、関数の識別子をパースする際に、rbpレジスタからのオフセットが格納されている変数を0にしてしまっていました。そのため、関数を呼び出すたびにrbpレジスタからのオフセットがリセットされてしまい、それ以降、宣言したローカル変数は、別のローカル変数とオフセットがかぶってしまいます。structを実装している時に、たまたまこのバグに気づいたのですが、structがバグの原因だと思い込んでいたため、解決に相当な時間を費やしてしまいました。バグの解決に大きく貢献したのは、gdbデバッガです。GDBを使用したデバッグ手法(応用編)というサイトを参考にさせていただきました。バグとして現れた症状は、知らない間にローカル変数の値が変わっているというものでした。そこでgdbデバッガのwatch機能を使用しその変数が変更されたときをbreak pointとしました。このサイトでは変数名を指定していますが、アセンブリコードのデバッグでは変数名は存在しません。しかしgdbデバッガはメモリのアドレスに対してもwatchすることができます。例を挙げるとwatch *0x7fffffffdd70
のような感じです。これでローカル変数が勝手に書き換えられているアセンブリコードの位置を特定し、そのコードを周辺をよく調べると、オフセットがかぶっている箇所がありました。それらを修正することで、正常に動作するようになりました。他にもgdbデバッガの便利な使い方があると思うので、調べてみたいです。
土日には寮祭がありました。私は寮生会の執行補佐という役職についているので、寮祭の企画、準備等に微量ながら関わらせていただきました。土曜日、日曜日の午前はバレーボールの試合を行い、日曜日の午後からミニゲームを行いました。
バレーボールの審判をしていたのですが、トーナメントで最後まで残ってくるチームはとても技術力が高く、三段攻撃を簡単にこなしており、スパイクやブロックなどが炸裂し、迫力がありました。審判という立場上、どちらかのチームを応援することもできず、感情を表に出せないため、ウズウズしていましたが、観戦している寮生は非常に盛り上がっていました。よかった!
日曜日の午後からはミニゲームを行いました。スリッパ飛ばし大会と、じゃんけん大会、マルバツクイズを行いました。スリッパ飛ばしは私も参加し、グループの中で2位でした。午前中の練習の成果が出せました(笑) 参加者も想像していたよりも多く盛り上がっていました。
総括すると大成功だったと思います。これだけ頑張ったので、来年も寮に残れることを期待しています!
さて来週したいことをメモしておきます、サークルの部活化のメリットをまとめた資料を作成(10/24までに)、自作Cコンパイラで2kmccをセルフホスト、物理のテスト勉強
今後触ってみたい技術や、したいこと。docker, gdbデバッガの応用, gitの応用, nvimでgitの変更点へジャンプするプラグイン、nvimで特定の位置に印をつけるプラグイン, nvimのバッファの概念