Как программа находит глобальную переменную внутри стека? - PullRequest
0 голосов
/ 11 сентября 2018

Насколько я знаю, когда я объявляю глобальную переменную int my_var;,
Это в фиксированный адрес в <bss> (неинициализированные глобальные данные) или <.rodata> (инициализация глобальных данных).

ex)

int my_var;          // <= It is at <.bss> section
int my_var = 0x1337; // <= It is at <.rodata> section

Итак, программа может найти эти статические значения, используя фиксированный адрес.

Проблема : Однако я слышал о глобальной переменной, расположенной в <stack>.

C запуска времени запуска инициализировать глобальную переменную: __environ, program_invocation_name
И они расположены в <stack> ...., что означает, что его адрес не является фиксированным.

Вопрос . Как программа может найти глобальную переменную внутри stack (нефиксированная область)?

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

__ environment и т.д ... не находятся в стеке;они являются обычными глобальными переменными, которые являются указателями (то есть переменной, значение которой является адресом) на места в стеке.Тот факт, что исходная программная среда, аргументы и т. Д. Находятся в стеке, является деталью реализации.Они также могут быть легко размещены в куче или в какой-либо другой области, подходящей для среды выполнения.

Единственное, что важно, - это то, что среда выполнения и операционная система договариваются о том, где их найти.

[отвечает на комментарий] Приведенная ниже программа должна иллюстрировать:

#include <stdio.h>
extern char **environ;

int main() {
 int x;
 printf("&envrion  = %p\n", &environ);
 printf("environ   = %p\n", environ);
 printf("*environ  = %p [%s]\n", *environ, *environ);
 printf("&x        = %p\n", &x);
 return 0;
}

в моей системе при запуске (cc -static xc; ./a.out) выдает:

&envrion  = 0x6bbda8
environ   = 0x7ffdd6edb3e8
*environ  = 0x7ffdd6edb9a2 [CLUTTER_IM_MODULE=xim]
&x        = 0x7ffdd6edb2a4

Обратите внимание, что & environment находится по адресу, который сильно отличается от окружающей среды, * environment и & x.Это потому, что последние находятся в стеке, а сама среда - нет.

0 голосов
/ 11 сентября 2018

Можете ли вы привести пример или ссылку на книгу с указанием глобальной переменной, хранящейся в стеке?

Смысл стека состоит в том, чтобы распределять память в соответствии с областью действия (временных) переменных, поэтому не имеет смысла использовать стек для «всегда живой» переменной (как вы сказали, есть другая разделы для этой цели).

Что касается вашего примера (int my_var = 0x1337;), инициализированная переменная не может быть размещена в секции только для чтения, поскольку это не означает, что она не будет изменена в какой-то момент (кроме решений компилятора).

Вопрос. Как программа может найти глобальную переменную внутри стека (нефиксированная область)?

Стек - это очередь LIFO, в которой указатель указывает последнюю позицию, а каждая временная переменная получает адрес (когда он создается в пределах границ стека), который указывает его местоположение, пока он не будет уничтожен (выходит из области видимости) и указатель стека обновляется. Но переменные среды не хранятся в стеке, они находятся над ним: https://www.thegeekstuff.com/2012/03/linux-processes-memory-layout/

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