導入
関数の中では、ローカル変数や退避したレジスタを置くために、スタック上に自分専用の区画 ―― スタックフレーム ―― を作ります。関数の定番の「型」を見て、全体像をまとめます。
説明
多くの関数はこんな「枠組み」で始まり、終わります。
myfunc:
push rbp ; 呼び出し元の rbp を退避
mov rbp, rsp ; 新しいフレームの基準点を rbp に設定
sub rsp, 16 ; ローカル変数用に 16 バイト確保
; --- ここで rbp を基準に [rbp-8] などにローカル変数を置く ---
; ... 関数の処理 ...
mov rsp, rbp ; 確保した領域を解放
pop rbp ; rbp を元に戻す
ret ; 呼び出し元へ戻る
push rbp/mov rbp, rsp… 関数の入口の定型(プロローグ)。rbpをその関数の「基準の杭」にします。[rbp - 8],[rbp - 16]… ローカル変数の置き場所。rbpからの相対で指します。- 出口(エピローグ)で領域を片付け、
retで戻ります。
まとめ ― このリファレンスで見たこと
- レジスタ … CPU 内の高速な小箱。
rax〜rdiと用途の慣習。 - 基本命令 …
mov(コピー)・add/sub(計算)・[ ](メモリ)。 - 制御構造 …
cmp+ 条件ジャンプでif・forを組む。 - スタックと関数 …
push/pop・call/ret、呼び出し規約とスタックフレーム。
高級言語の if も関数もループも、突き詰めればこれらの単純な命令の組み合わせでした。アセンブリを一度のぞくと、普段書くコードが「機械の上で何をしているか」を具体的にイメージできるようになります。より深く動かしたいときは、Compiler Explorer で自分の C コードがどんなアセンブリになるかを眺めてみてください。