関数パラメータアドレスアドレスを利用する問題

1754 ワード

以前はC言語でプログラミングをしていたとき、stackのレイアウトを利用していくつかの操作をしていました.私は以前、ゴミ収集アルゴリズムを実現するときに関数パラメータのアドレスを使っていましたが、このアドレスをベースにstack上で私の欲しいデータを探していました.この文章ではstackのレイアウトを詳しく紹介しています.コンパイラが関数をコンパイルする时に自动的に発生する前言や结语などの问题.このごみ収集アルゴリズムに兴味を持っているのはここを见ることができる.私はこのアルゴリズムを书く时clangコンパイラを使ってコンパイルすると,関数パラメータのstackでのレイアウトが予想と违うことを発见した.これはsfで提出した问题である.
その後、仕事の中でstack balanceに関する問題がたくさんありました.その中には反コンパイル後のコードを読まなければならない必要があります.
このような関数について
int add(int a, int b)
 {
      return a + b;
 }

clangでコンパイルした後、逆コンパイルの結果は以下の通りです.
 080483c0 :
    80483c0:   55                      push   %ebp
    80483c1:   89 e5                   mov    %esp,%ebp
    80483c3:   83 ec 08                sub    $0x8,%esp
    80483c6:   8b 45 0c                mov    0xc(%ebp),%eax
    80483c9:   8b 4d 08                mov    0x8(%ebp),%ecx
    80483cc:   89 4d fc                mov    %ecx,-0x4(%ebp)
    80483cf:   89 45 f8                mov    %eax,-0x8(%ebp)
    80483d2:   8b 45 fc                mov    -0x4(%ebp),%eax
    80483d5:   03 45 f8                add    -0x8(%ebp),%eax
    80483d8:   83 c4 08                add    $0x8,%esp
    80483db:   5d                      pop    %ebp
    80483dc:   c3                      ret
    80483dd:   0f 1f 00                nopl   (%eax)

中间に4つのmovコマンドがstackコピー操作をしているのが见えます.コピーするとstackレイアウトが
 +---------+
 |high     |
 +---------+
 |101      |

このステップのコピー操作により、パラメータのアドレスをアドレスとしてアドレスを指定することにエラーが発生する.ゴミ収集アルゴリズムを実現する際にclangのパラメータ計算順序の問題、あるいはABIの問題だと思っていたが、今では図のように見える.
振り返ってみると、clangは効率的に損失しますが、確かに論理的です.このようなパラメータコピー操作の後、関数のパラメータはすべて自分のframeの中にあり、以前のように関数のパラメータはcallerのframeの中にありません.この問題も説明しています.関数パラメータアドレスを利用するstack上のアドレス操作を行うことは潜在的なリスクがある.