2012-03-23 10 views
4

Linux Assembly Tutorial状態:アセンブリ:retを介して返されるラベルにジャンプすると、セグメンテーションフォルトが発生するのはなぜですか?

覚えておくべき1つの非常に重要なことがあります:あなたは(RET命令で)手続きから復帰することを計画している場合は、それにジャンプしないでください! 「決して!」のようにそうすることで、Linux上でセグメンテーション違反が発生します(これは問題ありません。すべてのプログラムが終了します)。しかしDOSでは、さまざまな程度の恐怖であなたの顔に爆発する可能性があります。

しかし、私ははそれがセグメンテーションフォールトが発生しない理由を理解することはできません。それはちょうど関数から戻るのと同じように聞こえる。

「Xが発生した場合は、手順Aを呼び出してください」というロジックを実装する必要がある状況があります。それ以外の場合は手順Bを呼び出します。カンガルーのようなスパゲッティコードのように飛び回る以外の方法はありますか?

+1

ちょうど注意してください:あなたがこれを行うことを特に妨げるものは何もありませんが、新しいアセンブリプログラマにとっては必ずしもそのことが明らかではありません。これの最も一般的なケースは「テールコール」と呼ばれ、関数型言語では一般的です。その効果はジャンプを含む関数の呼び出し元に戻ります(その関数の残りの部分をバイパスします)。*あなたがスタックの少しの部分をきれいにした場合。もしあなたがそうでなければ、それはセグメンテーションを見るときです。 – cHao

+1

'jmp'と' call'の違いを理解してください。 – hirschhornsalz

答えて

7

CALLが現在の命令アドレスをスタックにプッシュし、RETがコールサイトに戻るためにオフにします。 JMP(および関連する指示)は何もスタックにプッシュしません。

-1

このアドバイスはパイプラインと関係するかもしれませんが、わかりません。

私はあなたが求めている問題であると信じている:

... subroutine entrypoint ... 
... various instructions in a routine ... 
jmp label 
... move instructions in a routine... 
label: 
ret 

はこれで、あれば、問題は何ですか?まず、私はこれがまったく問題ではないと確信しています。しかし、そうであれば、それはパイプラインです。一部のプロセッサでは、の後に1つまたは複数の命令が実行され、制御がラベルに移る前に実行されます。

ほとんどの場合、あなたが読んだことを誤解しているか、あなたが書いたことを誤解してしまったのではないかと心配します。あなたのサブルーチンの1つの点からret命令へのjmp-ingは問題ありません。 retを実行する代わりにjmp-ingは、他の人が指摘したように、ダムの考えです。

+1

私は、 'call'命令を使うのではなく、単純な' jmp'を使って関数を呼び出すことができない理由を指摘しています。もちろん、スタックを自分で設定することもできます。それ以外の場合は、 'ret'がどこにも返らないため、これは失敗に終わります。 –

+1

私は、OPの引用は「ret命令にジャンプしないでください」という意味ではなく、「サブルーチンにジャンプせず、常にそれを呼び出す」ことを意味すると思います。 –

+0

はい、これが私の意図です。私が不明な場合は申し訳ありません:) – InvalidBrainException

関連する問題