昨日発生していたサイトログインできない不具合は修正されております(詳細はこちら)

OSコードリーディングブートキャンプ雑感

3
ほえほえ@スプシマン @hoehoe1234

無謀ともいえるC言語1日コース。伝えたいことはちょっと伝えられたかも。構文などは「for文あります」で終わりw。自分で調べていけるための要素を中心に講義。

2021-05-03 01:51:19
ほえほえ@スプシマン @hoehoe1234

メモリモデルは大切。テキストセグメント、データセグメント、スタックセグメント+ヒープあたりの「メモリモデル」がわかってないと変数の種類(クラス)がわからない。静的変数とローカル変数の仕組みと意味がわからない。構文なんか自分で調べればいい。必要なのC言語の本に「書いてないこと」。

2021-05-03 01:52:49
ほえほえ@スプシマン @hoehoe1234

仕組みから性質、挙動がくるのであって逆ではない。メモリモデルを抑えずして「ローカル変数は一時的」などといっても役に立たない。なぜ一時的なのかを仕組みを理解することで応用も洞察もできる。「変数は箱」でよいのだが「箱の種類と仕組み」を知る必要がある。

2021-05-03 01:54:18
ほえほえ@スプシマン @hoehoe1234

静的変数とローカル変数の仕組みを「メモリモデル」から知らずしてC言語のプログラムはできない。C言語は仕組みを直接使う言語だからしかたない。それに目的が 「OSコードリーディング」だからどうしても仕組み名にになる。

2021-05-03 01:55:21
ほえほえ@スプシマン @hoehoe1234

ポインタも多くの人がいうように「アセンブラからはいる」と分かりやすい。インデックスレジスタとレジスタの参照モードがあるからだ。この仕組を理解しているといないでは理解度が違う。

2021-05-03 01:56:20
ほえほえ@スプシマン @hoehoe1234

レジスタには型が(基本的に)ないので「間接参照のしくみ」だけが直接わかる。これがC言語をやったときに効いてくる。ポインタは間接参照+型だからだ。間接参照の仕組みがわからないのにポインタがわかるわけがない。なので多くの人がアセンブラを「ちょっとだけやれ」という。そしてそれは正しい。

2021-05-03 01:57:38
ほえほえ@スプシマン @hoehoe1234

次に記法。C言語の記法は式ベースで作った人たちが「自分たちのシステムを記述するため」に作ったので切れ味がいい。実践的なのだ。式を多様しているのでさまざまな書き方ができる。これは複雑さを生んで「いない」。むしろシンプルさを生んでいる。

2021-05-03 01:59:09
ほえほえ@スプシマン @hoehoe1234

さまざまな書き方が「個別」になるのではなく、ルールに従ってさまざまな書き方ができる。a+bはb+aと書いても複雑にならないのと同じ。1つ1つの記法の式評価を順番とその時点での型をたどっていけばわかる。

2021-05-03 02:00:18
ほえほえ@スプシマン @hoehoe1234

残念なのはワイが好きだったANSI C85の本を捨ててしまったこと。この本にはC言語のレールロードダイアグラムがついていた。ワイはこの本でC言語を勉強した。

2021-05-03 02:01:05
ほえほえ@スプシマン @hoehoe1234

演算子の結合順位は明確で識別子に対して ①後置演算子の複数回の適用 ②全治演算子の複数回の適用 ③式評価の値と副作用の区別 この3つだけでC言語の宣言と一見複雑そうに見える記号の羅列が明確に意味をもって浮かび上がる。

2021-05-03 02:02:34
ほえほえ@スプシマン @hoehoe1234

*p++ は *(p++) であるので結合は後置演算子が先、しかし、評価と副作用は、アセンブラの例にならえば tmp = p p = p +1   副作用 *tmp     式の値 (※tmpは内部的なもの) と理解すればよい。これもアセンブラを読む利点の一つ。いろいろな記法と表現方法がまなべる。

2021-05-03 02:05:41
ほえほえ@スプシマン @hoehoe1234

もう一つは実際にアセンブラを「すこしだけ」みること。静的変数はデータセグメントに、ローカル変数はBP相対で操作されていることが「実際に」わかる。これはおおきい。コードは確定している。なので変数の場所も確定している。しかし、ローカル変数はBP基準なので「実行時に動的にBPが変わる」。

2021-05-03 02:07:03
ほえほえ@スプシマン @hoehoe1234

これによりローカル変数は「実行している関数のBP基準」の場所が変数の位置になる。スタックにあるので積み重ねられるイメージとなる。コードは確定しているのに実行時に「ハードウエア」のしくみにより変数の場所が動的に変わる。これが「直接みれる」のは大きい。

2021-05-03 02:08:37
ほえほえ@スプシマン @hoehoe1234

多くのC言語の本は「C言語を教えるために」あるので本当のことは書いていない。それは意味がないからだ。これは目的から言って正しい。だけど今回のブートキャンプは「OSのコードを読むための基礎」なのでそのような変数の本当の姿を知る必要があり、おもにそのような観点から講義を行った次第。

2021-05-03 02:10:09
ほえほえ@スプシマン @hoehoe1234

ポインタ記法と配列記法の混在記法もなかなかわかりずらい。結局配列演算子[]とポインタ演算と参照外し*演算子が同一の結果を生むことを説明。ここは時間がなくてアセンブラのコードは見れなかったけど。記法の問題はとても大きい。記法をルールから理解できればコードを見たときに頭に入る。

2021-05-03 02:11:50
ほえほえ@スプシマン @hoehoe1234

1日かけてやった内容はこんな感じ。C言語の文法はほとんどやっていない。そうゆうのは書籍みればわかるからね。裏にあるモデル、ルール、記法の読み方のポイント・・・そういうのばかりやったかんじ。割と好評だったのでうれしい。 pic.twitter.com/RfOPm9VK3J

2021-05-03 02:13:36
拡大
ほえほえ@スプシマン @hoehoe1234

retunの仕組みはなんどもしている感じ。returnは「関数にもどるのではない」を理解しないとOSのコードは読めない。JSR/RSRなので概要としては「関数に戻る」でいいだけどコードを読むためにはその仕組を理解するひつようがある。

2021-05-03 02:16:44
ほえほえ@スプシマン @hoehoe1234

JSR(Jump subroutine)は、(一般的な使い方では)JSRコードの次の行をPCが指しているので、その値を「スタック」にPushしてからPCにジャンプ先関数の命令コード先頭をいれる。すなわち、ジャンプするのだ。

2021-05-03 02:18:16
ほえほえ@スプシマン @hoehoe1234

戻るときには「スタックからなんかしらんけど引き抜いてきて」その値の場所にジャンプする。そのような仕組みがあるので呼び出し関数からみると、関数を呼び出すと呼び出した次の行に返ってきたように「見える」。実際は呼び出したルーチンからジャンプしてきているにすぎない。

2021-05-03 02:19:30
ほえほえ@スプシマン @hoehoe1234

呼び出し元は呼び出す次の行をスタックにプッシュしてから呼び出す。呼び出された方はretrunでスタックからなんかしらんけどポップしてそこにジャンプする。そういう仕組みになっている。このスタック+ジャンプの仕組みがわかると、どうしてnewprocから1が返ってくるのかがわかる。

2021-05-03 02:20:54
ほえほえ@スプシマン @hoehoe1234

swtch関数からretunするときにスタック上に「newporcを呼びだ関数の呼び出し行の次の行アドレス」があればそれでいいのだ。そのようにスタックを操作しておけば「どんな関数からでもretrunしたらnewprocからもどったように」見える。戻り値はR0にあるので問題ない。

2021-05-03 02:22:14
ほえほえ@スプシマン @hoehoe1234

この2日のレジスタの説明とC言語の仕組みの説明で「随分理解が進んだ」という話をきいた。裏返せば最初からそのような説明が必要だったということでほえDX塾生の皆さんには迷惑をかけてしまったということになる。もうしわけない。

2021-05-03 02:23:31
ほえほえ@スプシマン @hoehoe1234

スタックの内容を基準にreturnしていることが理解できればnewporcが1を返す理由はわかる。newprocは1を返してない。他の関数がreturnしたときにスタック上にnewprocを呼び出した次の行にジャンプするのでnewprocから返ってきたようにみえるだけなのだ。

2021-05-03 02:24:40
ほえほえ@スプシマン @hoehoe1234

この3日の企画でワクワクVができなくて残念な気持ちもある。やはり実践アプリを作るのは楽しい。しかし、この基礎クラスがあったからこそ次の展開もみえてきたように思える。やはりOSコードリーディングはたのしい。

2021-05-03 02:25:52
ほえほえ@スプシマン @hoehoe1234

業務プログラムでは「業務の発見」はあってもプログラムの発見はない。逆にコードリーディングではプログラムの発見はあっても業務の発見はない。なので多くの場合は意図的に「コードリーディング」を行ってプログラムの発見を行わなければスキルの進歩はない。もちろん業務では上達するけど。

2021-05-03 02:30:32