Стек растет вверх или вниз - PullRequest
2 голосов
/ 14 ноября 2011

В некоторых местах я читал, что стеки растут с более высокого адреса на более низкий адрес, но когда я сам проверил его, я заметил, что он увеличивается с более низкого до более высокого адреса. Например, я выделил стек для потока по адресу 2aba5ab06010 и в какой-то момент обнаружил, что его значение равно 2aba5b7050f0 , что явно больше вершины стека.

Но когда я проверяю разборку, я вижу, что прологи функций вычитают% rsp, а эпилоги добавляют его, поэтому в этом смысле значение% rsp не должно быть меньше вершины стека. Почему эти противоречивые результаты?

Обратите внимание, что я использую Linux на 64-битной машине x86 и компилятор gcc.

Ответы [ 5 ]

6 голосов
/ 14 ноября 2011

Стек нитей может увеличиваться или уменьшаться в зависимости от платформы.Типичный способ проверить это: пусть A вызывает B функцию и с

void FunctionB( int* FromFunctionA )
{
   int localStackVariableB;
   //Compare &localStackVariableB and FromFunctionA addresses
}


 void FunctionA( )
{
   int localStackVariableA;
   FunctionB( &localStackVariableA) 
}

теперь сравнивает адрес localStackVariableB и FromFunctionA иопределить направление.Убедитесь, что оптимизация полностью отключена.

1 голос
/ 15 ноября 2011

Обычно, когда вы передаете адрес стека в функцию создания потока, вы передаете start выделенного блока памяти - это самый низкий адрес, и в системе, подобной x86 -64, где стек растет вниз, это низ стека. Однако новый поток начнет использовать стек сверху - самый высокий адрес.

Исходя из ваших цифр, мы можем сделать вывод, что ваш выделенный стек начинался с 0x2aba5ab06010 и был размером не менее 12 МБ, скажем, с 0x2aba5b706010. Если это так, это будет означать, что 3872 байта были использованы при ваших измерениях.

1 голос
/ 14 ноября 2011

Откажитесь от общего префикса (2ABA), и вы, похоже, претендуете на 0x5A... > 0x5B.... Нет, поэтому стек вырос вниз.

1 голос
/ 14 ноября 2011

В старые времена DOS раньше сегменты кода и данных загружались в начале сегмента памяти, и куча была выше этого. Затем стек находился на вершине сегмента памяти и увеличивался в направлении кучи, а куча росла по отношению к стеку. Современные системы редко так поступают.

0 голосов
/ 14 ноября 2011

Когда вы говорите, что выделили стек в 2aba5ab06010, вы имеете в виду, что вы дали ему кусок памяти стека, начиная с этого адреса? Тогда ваша контрольная точка будет выше начала выделенной памяти, но только с одной контрольной точкой вы не сможете точно определить, в каком направлении она растет.

...