以下は単純な C プログラムです。
#include <stdio.h>
int main(int argc, char* argv[] ){
int x = 10;
int* ptr = &x;
ptr++;
printf("%x %d \n", ptr, *ptr);
}
Ubuntu 64 ビットで GNU デバッガーを使用して、メイン関数の最初からプログラムを段階的にデバッグしました。これがデバッガーの結果です。
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffe0f8) at sigseg4.c:28
28 int main(int argc, char* argv[] ){
(gdb) display /a $sp
1: /a $sp = 0x7fffffffdfe0
(gdb) display /a $bp
2: /a $bp = 0xffffffffffffe010
(gdb) display /a &x
3: /a &x = 0x7fffffffdffc
(gdb) display /d x
4: /d x = 21845
(gdb) display /a &ptr
5: /a &ptr = 0x7fffffffe000
(gdb) display /a ptr
6: /a ptr = 0x7fffffffe0f0
(gdb) display /d *ptr
7: /d *ptr = 1
(gdb) next
29 int x = 10;
1: /a $sp = 0x7fffffffdfe0
2: /a $bp = 0xffffffffffffe010
3: /a &x = 0x7fffffffdffc
4: /d x = 21845
5: /a &ptr = 0x7fffffffe000
6: /a ptr = 0x7fffffffe0f0
7: /d *ptr = 1
(gdb) next
30 int* ptr = &x;
1: /a $sp = 0x7fffffffdfe0
2: /a $bp = 0xffffffffffffe010
3: /a &x = 0x7fffffffdffc
4: /d x = 10
5: /a &ptr = 0x7fffffffe000
6: /a ptr = 0x7fffffffe0f0
7: /d *ptr = 1
(gdb) next
31 ptr++;
1: /a $sp = 0x7fffffffdfe0
2: /a $bp = 0xffffffffffffe010
3: /a &x = 0x7fffffffdffc
4: /d x = 10
5: /a &ptr = 0x7fffffffe000
6: /a ptr = 0x7fffffffdffc
7: /d *ptr = 10
(gdb)
32 printf("%x %d \n", ptr, *ptr);
1: /a $sp = 0x7fffffffdfe0
2: /a $bp = 0xffffffffffffe010
3: /a &x = 0x7fffffffdffc
4: /d x = 10
5: /a &ptr = 0x7fffffffe000
6: /a ptr = 0x7fffffffe000
7: /d *ptr = -8192
(gdb) next
ffffe000 -8192
33 }
1: /a $sp = 0x7fffffffdfe0
2: /a $bp = 0xffffffffffffe010
3: /a &x = 0x7fffffffdffc
4: /d x = 10
5: /a &ptr = 0x7fffffffe000
6: /a ptr = 0x7fffffffe000
7: /d *ptr = -8192
(gdb) next
__libc_start_main (main=0x5555555546aa <main>, argc=1, argv=0x7fffffffe0f8,
init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffe0e8) at ../csu/libc-start.c:344
344 ../csu/libc-start.c: No such file or directory.
1: /a $sp = 0x7fffffffe020
2: /a $bp = 0x4720
(gdb) next
[Inferior 1 (process 9922) exited normally]
(gdb)
ご覧のとおり、x と ptr を初期化するとき、スタック ポインターはプログラム中に変更されません。私がオンラインで見つけたのは、x と ptr が実際にはメモリのスタック セグメントのレッド ゾーンに格納されていることです。
ただし、私を混乱させる部分は次のとおりです。まず、x を宣言して 10 に設定します。x のアドレスは 0x7ffffffffdffc です。次に、ポインター ptr を x に初期化すると、ptr は x のアドレスと同じ値になります。ただし、私の目を引いたのは、ポインター自体のアドレス: 0x7fffffffe0f0 が x のアドレス (e0f0-dffc = 4) よりも 4 バイト大きいことです。これは、スタックについて学んだことと矛盾しています。上向きではなく、メモリ。
レッド ゾーンはスタックとは異なる動作をしますか?