Assembly Nights
Assembly Nights (ratfactor.com)
要約
著者は、子供に読み聞かせをした後、古いAsus eeePCを使ってx86アセンブリ言語を書くという、ユニークな夜のルーティンを始めました。この習慣は、Zig言語への関心からシステムレベルのプログラミングへと深まり、最終的にコンピュータアーキテクチャやアセンブリ言語への探求につながりました。著者は、この小さなコンピュータと集中できる環境が学習に最適であると感じており、NASM構文でJonesForthを移植するプロジェクトに取り組んでいます。
全文翻訳
Assembly Nights
作成日: 2021-10-01
更新日: 2023-02-21
("seasons" を追加、プロジェクトページへのリンクを追加!)
この3ヶ月間、私は奇妙な夜のルーティンを開発しました。子供たちに寝物語を読んだ後、ベッドに入り、フィクションの本に手を伸ばす代わりに、14年前の Asus eeePC 701 (wikipedia.org)のミニチュアラップトップを起動し、x86アセンブリ言語を書いています。これは、私の時間を信じられないほど有効に活用することになっています…
[画像: ベッドの上でロマンチックに待つ、私の忠実なAsus eeePC 701]
私の忠実なeeePC 701は、2007年製の32ビットCeleron "ネットブック" ミニラップトップで、現在はAlpine Linuxを実行しており、ここでは私の非常に初期の作業中のNASMポート "JonesForth" を編集しています。この小さなコンピュータは、私が数えきれないほどのLinuxやBSDのバージョンを実行してきました!寒い夜には暖かくもあります。
Zigプログラミング言語 への私の関心が、私を "システムレベル" プログラミングへのより深い関心へと導き、それが最終的にコンピュータアーキテクチャ、命令セット、そしてアセンブリ言語へとつながるようです。
ああ、そして完成したプロジェクトには、独自のページもあります: nasmjf!
学習環境
説明できない理由で、私の小さなコンピュータとその小さなキーボードを使って、夜遅くに小さな命令を入力するのがしっくりきます。通常のデスクトップ開発マシンとは全く異なる環境にいることが、学習に適した気分にしてくれるのだと思います。
また、Lynx (wikipedia.org)をインストールしましたが、これは現代のウェブサーフィンには(ratfactor.comはもちろん別として)それほど優れたマシンではありません。そのため、非常に集中を妨げられないデバイスです。
この小さなコンピュータは他に何も使われていないため、この一つのタスクのためにゆっくりとカスタマイズしてきました。ログインすると、私の .bash_profile スクリプトはすぐにアセンブリプロジェクトディレクトリに cd します。
Vimでプロジェクトや関連ドキュメントを開いたり、GDBデバッガを起動して最後に作業していたブレークポイントでGDBスクリプトを実行したりする、小さくて難解な1文字または2文字のスクリプトやエイリアスをいくつか持っています。
これらの小さな工夫のおかげで、疲れていてあまり労力をかけたくない時でも、すぐに始めやすくなりました。今では、eeePCを手に取り、ログインし、アセンブリプロジェクトを開くことが、歯を磨くのと同じくらい自動的になりました。
では、このプロジェクトは何なのでしょうか?
JonesForthの移植
asmtutor.comのレッスンを終えた直後(リソースの下のNASMを参照)、私はずっと前に棚上げにしていた "バケットリスト" プロジェクトの一つ、Richard WM Jonesの JONESFORTH を読み、理解することに着手しました。
しかし、それをただ読むだけでは満足せず、NASMに移植することにしました。
アセンブリ全般、特にNASMには慣れていないため、進捗は信じられないほど遅いです。JonesForthはGAS(GNU Assembler)で書かれており、全く異なる構文を持っています。GASはしばしば操作されるデータのサイズをニーモニックの一部として含めるため、マシン命令のニーモニックさえも異なります。
最初の大きな課題は、GASからNASMへのいくつかの重要なマクロの移植でした。それぞれを理解して変換するのに数週間かかりました。
しかし、たとえ私の能力をはるかに超えるところから始まったとしても、些細なことではないものに取り組むのは、非常に素晴らしく満足のいくことです。何度も諦めそうになりましたが、ただひたすら努力を続け、障壁はゆっくりと崩れていきました。新しい命令が何をするのかを理解したり、バグを修正したりするたびに、それは小さな勝利です。
リポジトリ
さて、私の進捗状況を示すリポジトリはこちらです:
特に、ログファイル(log01.txt、log02.txtなど)をチェックしてください。それらは私の試行錯誤を記録しています。最初からやっていたらよかったのですが、今やっているだけでもありがたいです。
ゆっくり進む、プロセスを楽しむ、ツールを学ぶ
このセクションは更新です:
最近、私は "うっかり" JonesForthのポートに締め切りを設けました。今年中に蓄積した多くの小さなプロジェクトを終わらせて、来年に向けていくつか大きなプロジェクトに専念できるようにしたいのです。さて、その締め切りができた途端、何が起こったか? JonesForthのアセンブリのブロックを、できるだけ早くNASMに変換しようと急ぎ始めたのです。愚かですよね?
自分にゆっくり進むことを強制する必要があることを知っていました。しかし、言うは易く行うは難しです。緊急性は簡単に得られますが、失うのはそれほど簡単ではありません。
昨夜の "シャワーでの啓示"(これは元の記事を書いてから数日後です)は、どうすればゆっくり進むことができるかということでした。そして、それはこれです:翻訳中の作業を一旦止め、構文エラーがあれば修正してアセンブルできるようにし、そして、これまでに書いた すべての命令をステップ実行 して、すべてが期待通りに機能することを確認します。そして、それをより楽しくし、終わったときに努力の成果として何かを示すために、セッション全体をログに記録します。このコンピュータにはXさえ入っていないので、ログの明らかな選択肢は、ターミナルマルチプレクサであるGNU Screenです。
最初の考えは、「ああ、また新しいツールを学ばなければならず、完全に脇道にそれるのか!」でした。
次に考えたのは、「待てよ、それは素晴らしいことだ。」でした。これで、ついに別の広く普及しているGNUアプリケーションをきちんと学ぶことができ、自信を持って使えるツールがもう一つ増えることになります。さらに、Screenはあらゆる種類の利便性向上に役立つと思います。現在、Linuxの仮想端末(Alt-F1、Alt-F2など)を使用して、参照用にVimセッションとGDBセッションの両方を開いています。それらを自分で管理しなければなりません。Screenを使えば、単一のコマンドで両方のものを開くことを自動化し、Screenの Ctrl-a, Ctrl-a で切り替えられるようになると確信しています。
現在、GNU Screenユーザーマニュアル をすべて読んで、オプションを知るためにすべて試しています。その後、大きなGDBセッションをログに記録し、それをリポジトリの旅の別の成果物として追加できるトランスクリプトにしたいと思います。今、私は新しい機能の各ビットを探求する短いセッショントランスクリプトのシリーズを想像しています。これは本当に素晴らしいものになると思います。
(更新:これを実行しています!前述のように、リポジトリ のログファイルを確認してください。)
要点は、一時的に道を見失いかけたことです。この演習の「目的」を完成したForthポートだと考えていました。そうではありません。学習プロセスと私が習得するスキルが目的です。さらに、ポートが完了した後、Assembly NightsはForth Nightsに変わるでしょう。私のナイトスタンドには、Leo Brodieの Starting Forth と Thinking Forth があります。だから、この旅はかかるだけかかり、そしてそれは素晴らしいものになるでしょう。
ゆっくり進むことの心地よさ
私はプロジェクトが好きです。おそらく少し好きすぎます。私のプロジェクトのほとんどは失敗する運命にあります。すべて最初は成功するように見えます。しばしば、大きな絵の欠陥があり、楽しい詳細に集中していたために、プロジェクトが失敗すると気づくのが遅くなります。
私のプロジェクトのほとんどは明るく燃え、そして消えていきます。それはOKです!しかし、それが起こりすぎると、落ち込み始めることがあります。
しかし、私が気づいたのは、単に取り組むことによって成功が保証されるプロジェクトが実際にあるということです。そして偶然にも、現在そのようなプロジェクトが2つあります:
-
このプロジェクトと
-
私のhtmx例ページ - 各htmxコンセプトのコードサンプル(そしてくだらない動物の絵!)
どちらのプロジェクトもすでに明確な方向性が定められており、それらに取り組むどんな日でも、前進したことが 保証 されます。私はこれに慣れていませんが、それを楽しんでいます。報酬はゆっくりですが、失敗する方法はそれをやめることだけです。
心地よい!
リソース
NASM
NASMアセンブラには、単一のテキストファイル形式のドキュメントが付属しています。このファイルはアセンブリソースファイルと一緒に開いており、常にVimバッファからすぐにアクセスできます。これはこのHTMLバージョンと同じ内容です。
しかし、どこから始めればよいでしょうか?
私のパス(強くお勧めします)は、まずNASMのクリーンな "Intelスタイル" 構文でアセンブリの基本を学ぶことでした。そのため、私は 非常に 高くお勧めします:
Linuxコンピュータ(またはWindows上のWSLのような仮想環境)が必要になります。なぜなら、チュートリアルはLinuxシステムコールに依存しているからです。
私はeeePCで、裏で、携帯電話でasmtutor.comを開きながら、すべての演習を行いました!それは聞くほどいたずらなことです。
asmtutor.comが好きな理由(まさに探していたもので、完全に無料であることに加えて)は、多くの機能(Hello WorldからマルチスレッドWebサーバーまで)を一口サイズのレッスンでカバーしていることです。また、他のプロジェクトでジャンプスタートとして使用できる小さな関数のユーティリティライブラリを構築することになります。
これらのレッスンから、使用を通じて、非常に自然な方法で多くの理解を得ました。各レッスンは数段落の説明と、アセンブリプログラムで構成されています。私は常に例を微調整・変更して理解を深めるようにしているので、私のユーティリティ関数はかなり早い段階で元のものから逸脱し始めました。
とにかく、これらの演習で push、pop、call、ret を繰り返し使用したことは、高水準言語での長年の理論やプログラミングよりも、これらの基本的な概念を具体化するのに役立ちました。すごい、私は考え続けました、何年も前にアセンブリに飛び込むべきだった!
(実際、私は若い頃にDOSベースのx86アセンブリの本を読み、debug だけを使ってDOSアセンブリプログラムを書くのを楽しんでいましたが、それは私が本当に多くのプログラミングをする前のことでした。そのため、今回の経験は異なる影響を与え、定着しました。)
GDB
GDBは巨大で威圧的なソフトウェア(事実上オペレーティングシステム)なので、私は物理的な紙の本 Debugging with GDB: The GNU Source-Level Debugger をGNU Press/FSFから直接購入しました。週末にソファで本を読み、その夜eeePCで試すことをブックマークしました。
x86アセンブリ言語
Adam Ferrariによって書かれた、一般的な命令のリストを含む非常に優れた概要があります。最近、それがバージニア大学で "Intelスタイル" で存在することを発見しました:
そして、イェール大学でGAS/AT&T構文で存在します:
…しかし、私は実際に、この本が、すでに苦労して学んだことがある今、はるかに定着するだろうと信じています。これは私の学習に関するペット理論に完全に合致しています: ゲームマニュアルの現象。