最初の命令はpush bp
ので、スタックの一番上の値は、今bp
からの値です。
は、その後、あなたはsp
(スタックの最上位へのポインタ)の操作を含め、いくつかのより多くのことを行うが、ちょうどret
前に、それは古いbp
値に戻って指します。
ret
はスタックから値をポップし、その値にip
(命令ポインタ)を設定します。通常の状況下では、実行する次の命令のアドレスをスタックの先頭に置くことが期待されます(通常はcall
命令を実行します)。ret
のカウンタアクションを実行し、call
の次の命令のアドレスをスタックにプッシュしてからip
引数の値はcall
命令から)。
ip
は値が古いbp
に設定されています。この値はスタックメモリ(または「悪い」)のどこかを指している可能性が高いので、次にCPUがデータバイトをコードとして実行しようとします。 (OSへの復帰は実際には素晴らしい結果に終わりますが、そのような間違いは通常アプリケーションのクラッシュやデータの消失で終わります)。
修正するには、pop bp
をret
の前に追加してください(の値をmov sp,bp
に戻した後)。あなたはcall/ret
により、スタック、明示的push/pop
またはadd/sub sp
、または暗黙的で操作するたび
、あなたはさらに、スタックを使用する前に、すべてのコードパスで正しいsp
値で終わることを確認してください。つまり通常はpush
にはpop
のペアが必要で、すべてのcall
はret
で復帰する必要があります。ただし、そのようなルールを破るのに十分な経験がなければ、別の方法で正しい状態にスタックを調整する必要があります。
ところで、それは実際にがあなたのエントリポイントでのスタックでリターンアドレスがあり(これを-ingいくつかの他のコードcall
を持っている場合、それは、あなたの質問から明らかではない、またはそれがあるかどうか、疑問ですあなたのプログラムのエントリーポイント)。
これはDOS実行可能ファイルのようなもので、エントリポイントだった場合は、int 21h, 4Ch
OSサービスコールでプログラムを終了する必要があります。
あなたはどのアセンブラを使用していますか?また、質問は意味をなさない。あなたが*プログラムを実行するとき、*アセンブラ*は何かをしますか?問題を実行しているときにアセンブラは実行されません。コードをアセンブルしようとしているとき、またはバイナリを実行しようとしているときにこのメッセージが表示されますか?これは実際にはエラーであると確信していますか? –
あなたの質問は何ですか? – fuz
**「call twoMash」の後に**のコードは何ですか?あなたはそれを投稿していませんが、おそらくプログラムを終了させるでしょう( 'mov ax、4c00h'、' int 21h'のように)。 –