2

スタックの構造を理解するための小さなプログラムを書きました。

#include <stdio.h>

void function(int a, int b, int c) {
    char buffer1[5];
    char buffer2[10];

    int *ret = buffer1 + 13;
    (*ret) += 8;
}

int main() {
    int x = 0;
    function(1,2,3);
    x = 1;
    printf("x = %d\n",x);
    return 0;
}

今まで、スタックが以下のパターンに従うことを学びました

    ------------------
    |    arguments   |  High
    ------------------
    | return address |
    ------------------
    |       ebp      |
    ------------------
    |     buffer1    |
    ------------------
    |     buffer2    |  Low
    ------------------

また、5 バイトのデータを割り当てると、プログラムは 8 バイトを割り当てることも学びました (これは、ワード サイズの倍数でなければならないためです)。

function のアセンブラ コードのダンプfunction:

0x08048414 <+0>:    push   %ebp
0x08048415 <+1>:    mov    %esp,%ebp
0x08048417 <+3>:    sub    $0x20,%esp
0x0804841a <+6>:    lea    -0x9(%ebp),%eax
0x0804841d <+9>:    add    $0xd,%eax
0x08048420 <+12>:   mov    %eax,-0x4(%ebp)
0x08048423 <+15>:   mov    -0x4(%ebp),%eax
0x08048426 <+18>:   mov    (%eax),%eax
0x08048428 <+20>:   lea    0x8(%eax),%edx
0x0804842b <+23>:   mov    -0x4(%ebp),%eax
0x0804842e <+26>:   mov    %edx,(%eax)
0x08048430 <+28>:   leave  
0x08048431 <+29>:   ret    

アセンブラー・ダンプの終わり。

gdb の下でプログラムを実行すると、次のようになります。

(gdb) x/x $ebp
    0xbffff318: 0xbffff348
(gdb) x/x buffer1
    0xbffff30f: 0xfc73e461
(gdb) x/x buffer2
    0xbffff305: 0x0108049f

すべてがワードサイズの倍数で割り当てられている場合、buffer1との違いはどのようにbuffer2なるのでしょうか。10

9また、 %ebp との間にはどのような違いがありbuffer1ますか?

ここで正確に何が起こっているのですか?

:

  • スタックが High から Low に成長することを考慮してください
  • ワードサイズ = 4
  • Intel プロセッサ、Ubuntu 12.04、32 ビットを使用しています。

    gcc -o stack -g -fno-stack-protector -O0 main.c

構築する。

4

1 に答える 1