2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

"契約とは、自由を制限することで、秩序を得る行為である。"

コンピュータプログラムにおいて、関数とは小さな宇宙だ。
だが、その宇宙同士が出会い、交わり、協調するためには、
「秩序」が必要となる。

この秩序を支えるもの。
それが、**関数呼び出し規約(Calling Convention)**である。

この章では、呼び出し規約という静かな契約が、
どのように設計者間の信頼と相互作用を支えているかを探る。


関数呼び出し規約とは何か?

関数呼び出し規約とは、
**「関数間でデータをどのように受け渡し、制御をどのように戻すかを定めた取り決め」**である。

具体的には:

  • 引数をどこに置くか(レジスタか、スタックか)
  • 戻り値をどこに格納するか
  • どのレジスタを関数間で保存するか(callee-save / caller-save)
  • スタックポインタの管理ルール

この取り決めがなければ、
関数同士は互いを信頼できず、協調することはできない。


なぜ呼び出し規約が必要なのか?

理由は明確だ。

  • 関数同士は別々にコンパイルされることがある
  • ライブラリは外部からリンクされる
  • コンパイラはコード生成を最適化する必要がある

このとき、呼び出し規約という事前の約束がなければ、

  • 引数をどこで読むか分からない
  • 戻り先を間違える
  • レジスタ内容が破壊される

といった、破滅的な結果を招く。


呼び出し規約の具体例(x86)

例えば、x86の代表的な規約には:

  • cdecl
    • 引数は右から左にスタックに積む
    • 呼び出し側がスタックを片付ける
  • stdcall
    • 引数は右から左にスタックに積む
    • 呼び出される関数側がスタックを片付ける
  • fastcall
    • 最初の数個の引数をレジスタ(通常ECXとEDX)に渡す

どの規約を選ぶかで、

  • 関数の呼び出しコスト
  • 最適化しやすさ
  • インターフェースの柔軟性

が大きく変わる。


呼び出し規約の設計思想:自由か、制約か

呼び出し規約設計において、常に問われるのは:

  • レジスタをどこまで使う自由を許すか
  • スタックアクセスをどこまで規制するか
  • 呼び出し側と呼び出される側、どちらに責任を負わせるか

例えば:

  • callee-save重視(呼び出された側が保存)
    → 関数内部の自由度は高いが、負荷は関数側にかかる
  • caller-save重視(呼び出す側が保存)
    → 呼び出しコスト増大だが、関数自体はシンプル

このトレードオフは、
「局所最適」か「グローバル最適」かという、
設計哲学の選択でもある。


呼び出し規約の「見えない力」

普段、プログラマが意識しない場所で、
呼び出し規約は静かに機能している。

  • リンクされたライブラリ同士が、互いを理解できるのはなぜか
  • OSカーネルとユーザプログラムが安全に制御を渡し合えるのはなぜか
  • C、C++、Rust、Goなど異なる言語間で相互運用できるのはなぜか

そのすべては、
関数呼び出し規約という、静かな契約が存在するからである。


呼び出し規約を破ったとき、何が起きるか?

もし、呼び出し規約を無視して関数を呼び出すと:

  • 引数がずれる
  • スタックポインタが壊れる
  • 戻り先アドレスが破壊される
  • プログラムが即座にクラッシュする

これは単なるバグではない。
契約違反による、構造の崩壊である。


ABI(Application Binary Interface)と呼び出し規約

呼び出し規約は、より広い意味でのABI(アプリケーションバイナリインターフェース)の一部である。

ABIは:

  • データ型のサイズと配置
  • 呼び出し規約
  • バイナリフォーマット

を定め、
異なるコンパイラ、異なる言語、異なるプログラム間の共存を可能にする。

つまり、ABI=**「設計者たちの国際法」**のような存在である。


呼び出し規約を理解するとは何を意味するか?

呼び出し規約を理解するとは:

  • コードの深層構造を読む力を得ること
  • バイナリレベルでプログラムを解析する力を得ること
  • 自ら独自インターフェースを設計できる力を得ること

単なる関数の呼び出し手続きではない。
それは、**設計者同士が無言で握手を交わすための、最も基本的な「作法」**である。


結語:契約は、設計者たちの沈黙の言葉である

関数呼び出し規約は、見えない。
だがそれは確実に存在し、すべてを支えている。

  • 一貫した設計
  • 相互運用性
  • 信頼できる制御フロー

これらすべては、
静かに交わされた契約の上に成り立っている。

"設計とは、沈黙のうちに交わされた無数の契約でできている。呼び出し規約は、その最も静かで、最も強固な契約である。"

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?