4

私はアセンブリが初めてで、この記事に出くわしました

このコードは

void MyFunction()
{
  int a, b, c;
  a = 10;
  b = 5;
  c = 2;

これに等しい

push ebp     ; save the value of ebp
mov ebp, esp ; ebp now points to the top of the stack
sub esp, 12  ; space allocated on the stack for the local variables
mov [ebp -  4], 10  ; location of variable a
mov [ebp -  8], 5   ; location of b
mov [ebp - 12], 2   ; location of c

このビデオによると、ベース ポインターの上のスタックの値にアクセスするには、追加する必要があります。それがポインターの下にある場合は、減算する必要があります。上記の例を考えると、必要な変数の場所を移動するためにベースポインターから何かを差し引いていますが、これはビデオで述べられていることとは反対です。

私は何を取りこぼしたか?sub esp,12 はローカル変数にスペースを割り当てていることを知っているので、EBP がその割り当てを下回っていることを念頭に置いているので、マイナスではなく [ebp + 何か] である必要があると考えています。

彼がこのサブ esp 12 を実行したとき、スタックは次のようになります。

            ESP is here
|     2    | Ebp + 12
|     5    | Ebp + 8
|     4    | Ebp + 4
|          | Old EBP value

記事が間違っていたのですか、それとも私が解釈を誤ったのでしょうか?

4

2 に答える 2

6

ebp を使用する理由は、たとえばサブルーチンに引数を渡すなど、esp が変更されるためです。そのため、ebp は、esp がその瞬間にどこを指していても、同じオフセットを使用して同じ変数にアクセスできるようにします。

スタックに値をプッシュすると、その値が減少します。ポップすると増加します。

コードは 12 (4*3) を減算して、3 つの 32 ビット (4 バイト) 整数のためのスペースを作ります。Ebp は、esp が以前あった「底」を指します。したがって、ebp-4 などの負のオフセットを使用して変数にアクセスします。したがって、あなたの写真は間違っています: ebp+Whatever は、コードが操作してはならないものを指しています。

     BEFORE

     lower address
     |
     |<--------------  esp (=ebp after mov ebp, esp)
     |
     | 
     higher address


     AFTER mov ebp, esp; sub esp, 12

     lower address
     |<--------------  esp
     |
     |
     |<--------------  ebp
     |
     | 
     higher address


     AFTER mov [ebp-4], 10 ecc.

     lower address
     | 2  <--------------  esp
     | 5
     | 10
     |<--------------  ebp
     |
     | 
     higher address

この時点で、[esp][ebp-12]、つまり 2 が取得されます。

于 2013-05-22T08:48:53.027 に答える
2

( stack-pointerbase-pointer)-address は、アドレス空間の下位アドレスに向かって「成長」しています。
たとえば0x70000000、スタックはで始まり、pushその上に何かがあるとesp (ebp)、dwordによって低下します-> 0x6ffffffc(私が正しければ)。

ここここここを参照してください。

于 2013-05-22T08:32:55.853 に答える