2016-09-02 7 views
0

私はstrlenのように動作します機能解体:誰かがには、私にどのように動作するかを説明することができ Click here for picture誰かが私にはstrlenのこの分解を説明でき

を?私はそれが文字列の長さを得るために使われていることを知っています。

また、私がアセンブリについて常に混乱させていたことの1つは、変数をスタックに格納する方法です。それらは宣言(var _8、var _4、arg_0)の順序で格納されますか?彼らはebpから三日月形または減数形式で格納されていますか(格納されているアドレスを参照してください)? ebpはより価値の高いアドレスを持っていて、それはCのコンベンションと呼ばれていますが、逆にパスカルのコンベンションがあります。どのようになっているのかプログラムで使用されていますか?あなたの説明でこれらの質問に答えることができれば幸いです。

ありがとうございました。

+0

Cのvs pascalの引数は、ローカル変数とパラメータを混同しています。ほとんどの言語ではローカル変数には順序は必要ありませんが、単に順序がある必要があるため、残りの順序が存在する可能性があります。 –

+0

"strlenのような働きをする関数"なので、 'strlen'ではなく、それは何ですか? –

+0

@WeatherVane文字列を受け取り、それをループし、各サイクルの制御変数をインクリメントし、 '\ 0'文字に達したときに戻る関数です。 – SilenceOnTheWire

答えて

1

非常に最適化されていないアセンブリ言語のスニペットです。
ローカル変数はstack frameで使用されますが、多くのレジスタを自由に使用できます。

ご覧のとおり、は、その単一のパラメータがスタックを使用して転送されるためです。

この関数は、単一のパラメータ、[arg_0]zero terminated stringへのポインタのみをとります。
2つのローカル変数[var_4]があります。文字列の長さカウンタと[var_8]:文字列にpointerが実行されています。

中間ブロックは一度に1バイトの文字列を読み取り、そのバイトがゼロであるかどうかをテストします。もしそうなら、我々は完了し、長さを返すことができます。
もしそうでなければ、ひどく非効率な方法で文字列ポインタを増やし、長さカウンタを増やし、次のバイトをテストするために中間ブロックにジャンプして戻します。

ローカル変数の領域を作成するためのesp sub esp,8の操作はスタックフレームと呼ばれ、パスカルとC(最適化がオフの場合)はスタックフレームを生成します。
しかし、パスカル呼び出し規約はレジスタ(eax、edx、ecx)の最初の3つのパラメータを渡します。 Cはcdecl呼び出し規約を使用して、スタック上のすべてのパラメータをプッシュします。

これが終了すると、長さはeaxになります(すべての呼び出し規約の関数は、常に結果をeaxに返します)。
そして、それはスタックフレームクリーンアップ:それは近いリターンを使用して、呼び出し元に戻った後mov esp,ebp; pop ebp
を:retn

ローカル変数はebpからの負のオフセットを持っており、パラメータは持っているので、あなたは離れてローカル変数とパラメータを伝えることができますebpからの正のオフセット。

これは、最適化をオンにすることを忘れた場合に発生するコードです。
最適化されていないアセンブリコードを見ないと、悪い習慣を教え、あなたを啓発するのではなく、混乱させるようになります。

+1

最適化されていないアセンブリコードですが、まれです。これは、コンパイラの構築について学んでいるときに役立ちます。 –

関連する問題