2017-03-21 16 views
-2

英語それは私の最初の言語ではないので、私は間違っていくつかの単語を間違えて綴る場合。私はスタックにいくつかの問題を抱えています。私がここに入れるコードはすべて完璧に動作します。誰かが私にこのコードのスタックを説明できますか?

このコードは、たとえば簡単ですが、私はそのスタックを理解しています。

 

    .globl f 
    f: 

    push %ebx 
    movl 8(%esp), %eax 
    movl 12(%esp), %ebx 

    addl %ebx, %eax 

    ret 

STACK

 
    ------- 
    VAR Y --> ESP + 12 
    ------- 
    VAR X --> ESP + 8 
    ------- 
    RET --> RETURN 
    ------- 
    %EBX --> %ESP 
    ------- 

しかし、このコードで私はいくつかのトン

 

    .code32 

    .globl f 

    f: 

     pushl %ebx 

     movl 8(%esp), %ebx 

     subl $8, %esp # Creo posto nella stack per i parametri 

     movl $1, (%esp) 

     movl $2, 4(%esp) 

     call a 

     addl %ebx, %eax 

     addl $8, %esp #Tolgo posto nella stack 

     popl %ebx 

     ret 


完全にコードの仕事をしましたが、私はそれについて多くの質問をしました?。どこで%ebxとスタックがスタックにありますか? ASMの

コードはCでtransalted:

 

    int f(int x){ 

    return x + g(y,z); 

    } 

をそして、これは私が作ったスタックである

STACK

 

    -------- 
    8(%esp) --> x parameter of function f 
    -------- 
    4(%esp) --> z parameter of function g 
    -------- 
    (%esp) --> y parameter of funcion g 
    -------- 

そこで質問が今どこ%のEBXであり、このスタックを今すぐ復帰しますか?

答えて

0

最初のコードは、元の返信先ではなく、古いebxの値(おそらく有効なアドレスではない)に戻ります。より先にretがありません。 call a命令の前に、ss:espアドレスのメモリを呼び出す秒で

は、含まれています:ESPは動的に変化しないよう

dword 1      +0 (current esp) 
dword 2      +4 
dword old_ebx_value   +8 
dword return_address_from_f +12 
dword x      +16 
... older stack content ... 

あなたの「ESP + X」の表記は、動作しませんので、あなたがしたい場合そのようなスタックを記述するためには、あなたが使用しているコード(espの値)のどの位置にあるのかを述べる必要があります。つまりfのエントリでmov eax,[esp+4]は "x"をロードしますが、push ebxの後に同じことがmov eax,[esp+8](Intel構文では、自分自身で&のtterのシンタックスに変換されます。人間)。

でも、それをメモリ値として描画すると、それはすべてpushで動的に変更されるか、メモリに書き込まれるため、スタックを記述する実行ポイントを指定する必要がありますcall aの、call aaで先にその値1とコードの書かれた命令addl %ebx, %eaxのアドレスが疑問に示していないためだ。

とにかく古いebxとリターンアドレスが同じ場所でメモリ内のすべての時間です(aがそれらを上書きしない限り)、移動するコンテンツではありません。ポインタですespそれはpush/pop/add/subによって調整されています。 (メモリの内容は、popの後でさえ、一定の時間不定期に留まります。他のコードが上書きされるのにどれくらいの時間がかかります。SW割り込みハンドラがアプリケーションスタックを使用している場合は、時間は、x86 32bモードでは通常、アプリケーションはそれ自身のスタックを持っているので、それらの値はおそらくあなたが次のpushまたはcallまたは他の方法でそれらを上書きするまでそこにとどまるでしょう。

最後に、ちょうどそれらのものは、コンパイル、およびデバッガでそれらを実行して、最初にss:esp-32にメモリビューを入れ、メモリがcallまたはpushなどの指示によって書き込まれているか見に行って、どのようにespに変化しません「スタックの先頭」をポイントします。私の答えのようなテキストを読むよりも、デバッガで「見る」方がずっと簡単です。

関連する問題