1 名前:デフォルトの名無しさん mailto:sage [03/11/09 15:37] いろんなスレが乱立していますが、統合的なスレッドがないので立てました。 質問もOK 関連スレ C#って死滅する理由がないよね! Part4 pc2.2ch.net/test/read.cgi/tech/1042464104/ C#最強伝説 pc2.2ch.net/test/read.cgi/tech/1061208152/ C#とJava、どっちをおぼえればいいの? pc2.2ch.net/test/read.cgi/tech/1006715468/ C#Builder Professional 質問箱 pc2.2ch.net/test/read.cgi/tech/1062433418/ 関連リンク dir.yahoo.co.jp/Computers_and_Internet/Software/Programming_Tools/Programming_Languages/C_Sharp/
904 名前:898 mailto:sage [2008/06/15(日) 14:34:42 ] >>ともあれ、関数呼びだしに使われるスタックとデータ構造の議論でいうスタックは似ているが別のものってことで こういう中途半端な理屈で自分を納得させて学習を止めてしまうのが 一番良くありません。疑問があれば納得するまで調査するべきです。 私はCを勉強したての頃に前述の疑問を持ちその理由がよく説明 できませんでした。そこで自分なりに調べた結果、出した結論が 以下の答えです。 1)スタックはLIFO(Last In First Out)方式であり 後に入れたデータから先に読みだされる という記述の”読みだされる”というのがあたかもPOP をしたかのように誤解を与える記述ですが、実際は内部の 動作としては”値を読みだす(参照する)行為”は”POP操作” ではありません。スタックポインタが移動してないからです。 (続く)
905 名前:898 mailto:sage [2008/06/15(日) 14:35:26 ] 898のスタック構造は若干、はしょった部分があり正確には 関数add()内部でのスタック構造はこんな感じになります。 ebpレジスタ 変数 c (ローカル変数) 関数の戻り先アドレス 変数 a 変数 b (最後の引数から積まれる) (スタック領域の先頭アドレス) そして関数内部ではesp(スタックポインタ)を一旦ebpレジスタ に格納したうえで(アセンブラではmov (ebp,esp) )、変数a,変数b への参照を以下のように行っています。 変数a dword ptr[ebp+12] 変数b dword ptr[ebp+16] 変数c dword ptr[ebp+4] add()関数内部の処理はこれらをアキュムレータで演算しているに 過ぎません。 (続く)
906 名前:898 mailto:sage [2008/06/15(日) 14:37:19 ] 関数を抜けるときに初めてPOPが行われます。 1)変数cをPOP 2)POPで呼び出し元に復帰 3)変数aをPOP 4)変数bをPOP ※実際にはPOPを行わずにスタックポインタの値を進める事で 代用する場合が多いです。 結局、関数の中でスタックに積まれた引数やローカル変数の値 を使用することはスタックからそのデータを取り出した(POPした) わけではないのだから、スタックの定義と全く矛盾しませんよ ということを言うためにこんなまわりくどい説明をしました。 でも、案外誤解している人って多いかもしれないと思います。 なお、これらは日経BP社の「プログラムはなぜ動くのか」という 本の第10章「アセンブリ言語からプログラムの本当の姿を知る」 を読めば完全に理解できると思います。 (終)