低レイヤーのはじめの一歩
今年は年始辺りから低レイヤー周りの勉強を始めている.
はじめは Z80 アセンブリを macOS 上のエミュレータで動作させるところからスタートした.
この動画 を参考に、z80pack に
付属している Z80 アセンブラ z80asm とエミュレータ z80sim を使って はじめて読むマシン語 の
サンプルプログラムを自分で動かしてみたりしていた.
ただ、DB 命令を使うサンプルでは z80asm が DB を疑似命令として認識しないようであったため、
一部 z80asm の代わりに zasm を使った.
z80asm と z80sim は組み合わせて使う分にはとても快適なのだが、生成/実行される機械語プログラムの先頭にどうも 0xFF 0xYY 0xXX というフォーマットの 3 バイトのヘッダを付与することを前提としているようだ.
この 3 バイトのうち、0xYY と 0xXX はアセンブリコード中で ORG 0xXXYY と指定したエントリポイントのアドレスがそのまま挿入されるらしく、zasm で生成した機械語プログラムを z80sim で正しく読み込むためにはこの 3 バイトのヘッダ情報を自分で付与してやる必要があった.
いずれにしても、低レイヤー周りの知識を一切持たなかった身としては Z80 アセンブリはとても良い導入であったと思う. Zilog 社が開発した Z80 は非常に古い 8 ビット CPU ではあるが、Intel が発売した 8 ビット CPU である 8080 の完全な上位互換を持っている. Intel は後に、8080 を拡張することで 16 ビット CPU である 8086 を開発し、更にはその 8086 を拡張することで 32 ビット CPU である 386 を開発している. そしてこの 386 は 486 や Pentium 以降の全ての現在の Intel x86/64 CPU の先祖となっている. したがって、Z80 アセンブリの特徴は現代の Intel CPU にも共通する部分が多いといえる. (CISC、リトルエンディアン、など.)
当然、8 ビット CPU であるので大した処理は書けない. しかし、後に x86 アセンブリを学習することも踏まえるならば、いきなり複雑な x86 から入るよりも Z80 のような単純でしかも基本的な考え方が x86 に似ているアセンブリ言語から入るほうが理解のしやすさが全然異なると思う.
(そもそも汎用レジスタのとっつきやすさからして違うと思う. 予備知識無しでいきなり eax とか rax とかを眺めるよりも、まず 8 ビット時代には A レジスタというレジスタが存在し、そのレジスタはアキュムレータ (“A"ccumulator) として使われ… といった予備知識がある方が僕には分かりやすかった.)
Z80 アセンブリ言語は大変勉強になった. 調べてみると Z80 はかなり幅広く使われていた (る?) CPU のようで、ゲームボーイや MSX シリーズ、PC-88 シリーズなどでも採用されていたらしい. そのうち、Z80 のエミュレータは作ってみたい.
その後、自作エミュレータで学ぶ x86 アーキテクチャ を読んで x86 アーキテクチャに入門してみた. Intel の Software Developer Manuals も参照しながら、手を動かして一通り読了したが、とにかく ModR/M が面倒だった.
この本のサンプルは基本的に Windows 上で動作させることを前提としている. エミュレータ自体のコードは普通の C 言語であるため特にどの OS でも問題ないのだが、厄介なのは 作成中のエミュレータに読み込ませるテストプログラム である. エミュレータを自作する側からすると、エミュレータに読み込まれるテストプログラムが期待した通りのバイト列 (機械語) であるかは非常に重要であるが、C 言語で書かれたプログラムがコンパイラによって必ず同一の機械語に翻訳される保証はない. コンパイラの種類やバージョンが異なれば生成される機械語も異なる可能性がある.
結論から言うと、僕はテストプログラムのコンパイルは VM 上の Windows で行い、生成されたバイナリを macOS 上に持ってくることで対処した. すなわち macOS ではエミュレータ本体に関連する作業しか行わないことにした. 本文中で解説されている gcc および ld へのオプション指定でハマりまくった上、(当たり前なのだが) 期待したとおりのバイナリが生成されるかどうかの保証がないという事実に直面した辺りで心が折れたためである.
とりあえず、macOS 環境下での環境構築奮闘記を別の記事でまとめておくことにしたが、たぶん参考にならない. ただ、本の内容自体はかなり面白く、x86 でのスタックフレームの取り扱いについてや基本的なエミュレータの動作原理を知ることができたのは大きな収穫だった.
その後は 30 日でできる!OS 自作入門 を macOS 上で読み進めてみた. これも元々は Windows 環境向けの本だったのだが、現在は有志の方が macOS 上でも開発できるように 開発ツール を公開してくれている. 大変ありがたい. が、それでも開発ツール周りでハマるとなかなか辛いものがある. 半分程度読んだところでこの本は一旦積読中になってしまったので、そのうち再開したい.
最近は 低レベルプログラミング も気になっているんだけども、いつ読めるのかは不明…