web-dev-qa-db-ja.com

アセンブラーx86関数呼び出しでパラメーターを渡す方法

このアセンブラコードを見てください。 32ビットx86用に設計されており、nasmによってコンパイルされます。

   ...
   my_function:
        pop %eax
        ...
        ret


   main:
       Push 0x08
       call my_function

私はずっと前に、メインプログラムと関数の間でパラメータを渡すためにスタックを使用できることを学びました。 eaxには0x08が含まれていると思いますが、これは偽であり、理由を説明できません。関数パラメーターを取得するにはどうすればよいですか?

9
Bob5421

まず、プラットフォーム上の他の言語またはライブラリとのインターフェイスを探している場合は、そのプラットフォーム用に定義されたインターフェイスを必ず読んでください。使用される可能性のあるさまざまな呼び出しメカニズムがあります。

あなたの場合、call命令は戻りアドレスをスタックにプッシュしています。算術演算とespを使用して、パラメーターにアクセスできます。 eaxを使用しているため、32ビットコード(および32ビットスタック幅)を想定します。私は何も調べずにそれを書くことができるので、インテルの構文を使用しています:

my_function:
    mov eax, [esp+4]    ; Move the contents of ESP+4 into EAX
                        ; ESP should be pointing at the 32 bit RIP.
                        ; ESP+4 should be the pushed parameter.
    ...
    ret


main:
   Push 0x08
   call my_function

この回答に関して、これがメモリリークを表しているかどうかをコメントでお尋ねください。答えはいいえだ。"理由は、callerがスタックに追加するものをすべてクリーンアップする責任があるためです。作成された他のコメントに基づくより完全な例は、次のようになります。

my_function:
    Push ebp            ; Store the current stack frame
    mov  ebp, esp       ; Preserve ESP into EBP for argument references
    and  esp, 0xfffffff0; Align the stack to allow library calls
    mov  eax, [ebp+8]   ; Move the contents of EBP+4 into EAX
                        ; EBP should be pointing at the 32 bit RIP.
                        ; EBP+4 should be the pushed parameter.
    ...                 ; Do lots of cool stuff
    mov  esp, ebp       ; Restore the stack and ebp
    pop  ebp
    ret


main:
   Push 0x08
   call my_function
   pop ebx              ; Clean up the stack

スタックを16バイト境界に揃える場合(これがなぜ発生するのかわからない場合、プラットフォームの呼び出し標準を調べるとすぐに見つかります)、どのように理解することも試みないことに注意してください多くのespが変更されました。 ebpは「しおり」として機能するため、espを移動させて、他のことを考慮せずにアライメントやローカル変数の割り当てを行うことができます。

関数のエピローグでは、ebpespに戻し、関数が呼び出されたときにespを元の値に復元します。これにより、起こりました。最後に、pop ebpスタックから離れ、関数内のスタックの最終値として戻りポインターを残します。戻りました。

戻った後、ポップでクリーンアップします。

または、スタックで解放するバイト数を指定する戻り値でスタックをクリーンアップすることもできます。それはすべて、呼び出し元の標準が呼び出し元のクリーンアップまたは呼び出し先のクリーンアップを指定しているかどうかに依存します。

8
David Hoelzer