関数呼び出しがどうやって実装されているか

 

アセンブラでの関数呼び出しは以下のように実装されていることが多い。

呼び出す側の関数をA、呼び出される側の関数をBとする

例えば、

int sum(int a, int b){

  return a+b

}

void main(){

   sum(1,2)

}

ならmainがA, sumがBを指す

  1. 引数をスタックに積む
  2. Aに戻った際に次に実行すべき命令が格納されているアドレスをスタックに積む
  3. Aを実行していたときのベースレジスタを積む
  4. ebpを退避しておいて、ebpにespを代入する
  5. ebpを基準に引数を取得する(例えばこの時、途中で関数呼び出しがあっても、ebp+4で引数が呼べる)
  6. 関数から戻る時はこれと逆の処理をする