Понимание стека и красной зоны C-программы - PullRequest
0 голосов
/ 21 марта 2019

Вот простая программа на C:

#include <stdio.h>
int main(int argc, char* argv[] ){
    int x = 10;
    int* ptr = &x;
    ptr++;
    printf("%x   %d \n",  ptr,  *ptr);
}

Используя отладчик GNU на Ubuntu 64-bit, я пошагово отлаживал программу от начала основной функции, и это результат отладчика:

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: 0x7fffffffdffc.Затем мы инициализируем указатель ptr на x, в результате чего ptr имеет то же значение, что и адрес x.Однако, что привлекло мое внимание, так это то, что адрес самого указателя: 0x7fffffffe0f0 на 4 байта больше, чем адрес x (e0f0-dffc = 4), что противоречит тому, что я узнал о стеке, что он растет вниз впамяти, а не вверх.
Красная зона как-то ведет себя иначе, чем в стеке?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...