このブログは、旧・はてなダイアリー「檜山正幸のキマイラ飼育記 メモ編」(http://d.hatena.ne.jp/m-hiyama-memo/)のデータを移行・保存したものであり、今後(2019年1月以降)更新の予定はありません。

今後の更新は、新しいブログ http://m-hiyama-memo.hatenablog.com/ で行います。

Toyアーキテクチャのヒント

単に箇条書きで羅列。

  1. 昔はスタックがない機械もあったらしい。まー、自前でも作れるが、メンドーだからスタックはあったほうがいい。
  2. 明確なコール/リターン命令がない機械もある。が、メンドーだからあったほうがいい。
  3. コールで、戻り番地(当該命令の次の番地)をリンクレジスタに入れる方式と、スタックに積む方式がある。呼び出しが入れ子になれば、どっちにしろスタックに積むことになる。よってスタックに積む。
  4. fp(フレームポインタ)がフレーム内のどこを指すかは勝手。そもそもフレームの定義もいろいろ。
  5. fpがない、使わない方式もあるらしいが、使おう。
  6. 引数は「呼び側の領域か、呼ばれ側の領域か?」微妙だ。
  7. fpはローカル変数が始まるところを指すのがいいと思う。最初or最後の引数のを指す方式もある。
  8. sp(スタックポインタ)を大量に増減させるとき、pop/pushは不向き。
  9. インテルのretはスタックトップにあるアドレスにジャンプする。
  10. 関数内のプロローグコード(入り口)、エピローグコード(出口)は色々。
  11. インテルCPU + Cでは、(1) 今のbp(fpと同じ)をスタックに積む(待避) (2) 今のspをbpに設定(bpが今のスタックトップを指し、スタックトップにはbp待避値) (3) ローカル領域分spを増やす(実際は引き算)。
  12. 同じくエピローグコードは、(1)spをbpにセット (2)popでスタックトップをbpに入れる(古いbpを回復) (3)retでスタックトップにあるアドレスにジャンプ(戻り番地はpopされる)
  13. インテルでは、エピローグ用にenter、プロローグ用にleaveがある。
  14. よって、call, enter, ...., leave, ret となる。
  15. レジスタの保存は規約の問題
  16. MIPSだと、temporaryレジスタは呼び側の責任、その他は呼ばれたほうで待避と回復をする。
  17. 汎用レジスタに関しては、どっちか一方の責任にしてもいいような気がする。
  18. ジャンプの飛び先をターゲットアドレスと呼ぶことがある。
  19. インテル対象のアセンブリ言語では、mov α,β は α→β の方向のコピー。cpコマンドと同じだが、代入とは逆。
  20. レジスタを使うときは、左の引数から順にレジスタに割り当て、残りは右から順にスタックに積み上げるのが普通。
  21. 可変引数があると、左からスタックに積むと、1番目の引数が特定できない。
  22. インテルでは、bp(fp)がローカルデータのはじまりを指す。
  23. 結局、引数右→引数左→戻り番地→1つ前のbp→ローカルデータ
  24. 引数を積むのは呼び側、戻り番地はcall命令、以前のbpはプロローグ(enter)が積む。新しいbpのセットもプロローグコード。
  25. 最初の(最後に積んだ)引数とローカルデータの間に戻り番地と旧bpで8バイト分使う。

それと、参考になりそうなスライド: