KDOC 140: 『自作エミュレータで学ぶx86アーキテクチャ』

この文書のステータス

  • 作成
    • 2024-05-12 貴島
  • レビュー
    • 2024-05-19 貴島

概要

自作エミュレータで学ぶx86アーキテクチャ コンピュータが動く仕組みを徹底理解は、エミュレータを作りながらCPUまわりを詳しく易しく説明する本。

メモ

  • プログラマの視点では変数はレジスタではなくメモリに置かれることになっているが、コンパイラからするとどちらもある。最適化のためにレジスタに置くこともある
  • カウンタ変数をレジスタに置くことでカウンタの更新が早くなり、ループの実行速度が改善する
  • ポインタ変数に範囲外の値を書き込む実験がおもしろい(57ページ)

添字は加算の糖衣構文にすぎない。加算は入れ替えられる。

// 2つの記法は等しい
// arr[0]
// *(0 + arr)
int arr[2];
0[arr] = 1;
1[arr] = 2;
/* arr : {1, 2} */
  • ローカル変数のポインタを返せてしまう。関数を抜けたときに破棄されるので、「宙に浮いたポインタ」となる(59ページ)
  • X->Y(*X).Y の糖衣構文
  • ある型の変数を定義するときは、その型の大きさをわかっている必要がある。大きさがわからないと、コンパイラがどれくらいのメモリを割り当てるか判断できないから
  • サイズがわからない型のことを不完全型という
    • void型も不完全型の一種
  • 何らかの型へのポインタ型とvoidへのポインタ型は相互に変換できるとCの規格で保証されている
  • 関数ポインタの箇所がよくわからなかった(68ページ)
  • CPUが機械語プログラムを実行するためにはそのプログラムをメインメモリに配置する必要がある
  • 80ページの汎用レジスタの表。
名前 別名 主な役割
---    
eax アキュムレータ 値を累積する
ebx ベース メモリ番地を記憶する
ecx カウンタ 文字列の添字やループの回数を数える
edx データ I/O装置の番地を記憶する
esi ソースインデックス 入力データの添字を記憶する
edi デスティネーションインデックス 出力データの添字を記憶する
esp スタックポインタ スタックの先頭を指す
ebp ベースポインタ スタック上の何らかのデータを指す
  • レジスタの由来が面白い(p82)
  • CPUが命令を実行する流れ(p86)
  • ModR/Mがよくわからない(p96)
  • push,popのおさらい(p105)
  • eipが関わる命令は専用の命令になっている場合が多い
  • 関数呼び出しの図(p109)
  • ebpを基準にしてスタック上での変数の位置をさす(p121)
  • スタックフレームを16バイトの倍数で確保しようとする。コンパイラはなるべくアラインメントを揃えるように調整した機械語を作り出そうとする。一気に読み込めて高速だから(p122)
  • leave命令(p122)
    • 1. mov esp, ebp … espにebpを書き込む。スタックの先頭がスタックフレームの先頭まで巻き戻される
    • 2. pop ebp … 先頭に古いebpの値が積んである状態になる。ebpの値を復元する
  • cmpはsubと同じ計算し、同じようにフラグを設定するが、オペランドを変更しない点がsubと違う。cmp条件分岐命令のためにオペランドの大小関係を比較する専用命令といえる(p124)
  • for文をアセンブリで見る(p133)。まず条件式の処理にジャンプするのはコンパイラが繰り返しをアセンブリに変換するときによく使う。
  • ifとgotoで書き直した例。ほぼ同じになる(p135)
  • I/Oポートの読み書きで1文字の入出力をする周辺機器を作る(p145)
  • io/out命令だけで、紙と鉛筆で文字が書けるように、すべての周辺機器を制御できる(p148)
  • \x1b0x1b という1バイトを表す。これはC言語の機能で、 \xYY と書くと16進数のYYを表せる。文字コードのことが多い(p155)
    • なので、 \x1b[32m はデータ的には5文字で、それ以降の文字を緑にする
    • 戻すのは \x1b[0m
    • \x1b[輝度;色番号mこれは色付き文字\x1b[0m
  • 割り込み時に呼び出すサブルーチンの先頭番地を登録しておくための特別なメモリ領域、割り込みベクタテーブルがある(p160)
  • int命令では割り込み番号さえわかればハンドラを呼び出せる。サブルーチンの名前や番地がわからなくてよい(p160)
  • int命令の割り込み番号3はブレークポイントを設定するのに適した機能。デバッグ対象のプログラムを任意の場所で中断し、各レジスタの値やスタックを確認できる。割り込みで実現している(p162)

関連

Backlinks