大熱血!アセンブラ入門part2メモ
このpartのエッセンスだと感じたことをメモ。
なお、part2はpart1で培ったアセンブラの読み方を使ってとにかく読み漁ってみようみたいなpartになっていました。アセンブラを適切なコーチングのもとに読む練習をしたいと思ってこの書籍を購入した私にとっては、待っていました!というようなpartでした。
・下記のようなアセンブラの業界用語を知っていると幸せになれる。
レジスタウィンドウ:仮想的にレジスタ層のようなものを作っておき、関数呼び出しの際に自動的にその層を切り替える。メリットはレジスタの保存の必要性がないこと。つまりレジスタの退避のための命令をせずに済むということ。
PC:Program Counterのこと。現在実行中のアドレスを保持するレジスタ。
PC相対:ディスプレースメント付きレジスタ間接の反対語?アドレス指定の方法として、"PCの"アドレス値に即値を足すという方法を採用すること。
ディスプレースメント付きレジスタ間接:PC相対の反対語?アドレス指定の方法として、"レジスタの"アドレス値に即値を足すという方法を採用すること。
PIC:Position Independent Codeの略。共有ライブラリが仮想アドレス上のどのアドレスにマッピングされても動作可能なようになっている機械語のこと。
機械語:CPUが処理可能な情報。だいたい、バイナリ値のことを指す。
VLIW:数命令を並列に同時実行する仕組み。イメージ的には、まとめてドカーンという感じ。
メモリマップドI/O:I/Oレジスタをメモリアドレス上にマッピングして、ロードストア命令によって読み書きする。
プリデクリメント:フルスタックの場合に、スタックポインタを減算してからそこに値を格納すること。
フルスタック:使用中領域の終端をスタックポインタが表すこと。要は、スタックフレーム(関数の内容等)がぎっしり詰まっているメモリの先端アドレスをスタックポインタが示していること。
エンプティスタック:フルスタックとは違って、未使用領域のアドレスを指定すること。確保していない領域にいきなり値を設定した後に、スタックポインタを減算する。(ポストデクリメント)
ダイレクトアドレッシング:低位のアドレスをアドレス直接指定でアクセスすることでまるで汎用レジスタのように扱うこと。
命令の直交性:全ての命令で全てのオペランドを扱えるようにすること。CISCの思想。
パディング:決まったバイト列で空いてしまったバイト列を埋めること。」
アウトオブオーダー実行:OoOと略される。命令列の順番をCPUが適切に入れ替えながら実行すること。
・ディスプレースメントを利用しないでアドレスを取得する=加算処理でアドレス指定する
・引数を割り当てられるレジスタは暗記しておいたほうが読みやすい。
・戻り値をとるレジスタは暗記しておいたほうが読みやすい。
・中途半端な即値を表現するために、0付近の値を反転させて表現することがある。
例:0x11223344を0xffeeddccをビット反転させて表現する。
・関数呼び出しの際に、スタックポインタに数字"足していたら"上方伸長。スタックポインタから数字を"引いていたら"下方伸長。
・全ての処理に共通するような処理はわからなかったら「おまじないのようなものだろう」で読み飛ばす。
・PCの値を取得したい時に、次の命令に対して関数コールしてしまう常套手段がある。アセンブラ中に直後の命令を関数コールしていたらこの常套手段を利用している。
・(言われてみれば当たり前だが)or演算は加算のような繰り上がりが存在しない。特定のビット列にのみ演算をしたい場合には有効な手段。
・「多バイト値の演算は、値は付近において、PC相対でその値をロードして行う」というやり方を頭にいれておく。しかしPC相対でロードするにしても範囲指定を行うビットは限定されているので、そんなに遠くに置くことはできない。(ロードする値は、ロードしようとする命令の近くにあるということ。また範囲指定を行うビット列がいくつかを予め知っておけば最悪虱潰しにロード値を探すことができるということ)
part2を経て、最低限どのような意識で読めばいいのかを理解できる。しかし本気で詳細に理解したかったら、ある程度頭に入れておくべき情報がある。私が現時点で感じているのは下記。CTFではIntelのアーキテクチャがでるのかな?
・引数レジスタ
・戻り値レジスタ
・演算方向(→か←か)
・よく使われるオペコード
・上方伸長か下方伸長か
次はpart3。アセンブラ出力環境を構築する、というpartらしいので、詰まったポイントだけ記述する予定。