Как найти стек увеличивается или уменьшается в C? - PullRequest
0 голосов
/ 13 февраля 2011

стек увеличивается или уменьшается с помощью программы на C?

Ответы [ 6 ]

8 голосов
/ 13 февраля 2011

Правильно, в C обычно переменные в области действия функции реализуются с помощью стека.Но эта модель не навязана стандартом C, компилятор может реализовать это любым удобным для нее способом.Слово «стек» даже не упоминается в стандарте, и даже меньше, если оно увеличивается или уменьшается.Вы никогда не должны пытаться работать с предположениями об этом.

2 голосов
/ 13 февраля 2011

Ложная дихотомия.Существует множество опций, кроме увеличения или уменьшения, одна из которых заключается в том, что каждый вызов функции выполняет эквивалент malloc для получения памяти для автоматического хранения вызываемого, вызывает вызываемого и выполняет эквивалент free после возврата,Более сложная версия этого будет выделять большие партии «стека» за раз и выделять больше только тогда, когда он будет исчерпан.но они могут иметь смысл при реализации многопроцессорной операционной системы на микропроцессорах без MMU, где резервирование диапазона памяти для стека в каждом процессе приведет к потере большого количества адресного пространства.

1 голос
/ 13 февраля 2011

Как насчет:

int stack_direction(void *pointer_to_local)
{
     int other_local;

     return (&other_local > pointer_to_local) ? 1 : -1;
}

...
int local;
printf("direction: %i", stack_direction(&local);

Итак, вы сравниваете адрес переменной в одном месте в стеке вызовов с адресом во внешнем месте.

0 голосов
/ 13 февраля 2011

Вы также можете отслеживать регистр ESP с помощью встроенной сборки.Регистр ESP содержит адрес незанятого стека.Так что, если что-то помещается в стек - ESP уменьшается, а если всплывает - ESP увеличивается.(Существуют другие команды, которые изменяют стек, например, вызов / возврат функции).

Например, что происходит со стеком, когда мы пытаемся вычислить рекурсивную функцию, такую ​​как число Фибоначчи (Visual Studio):

#include <stdio.h>

int FibonacciNumber(int n) {
    int stackpointer = 0;
    __asm {
        mov stackpointer, esp
    }
    printf("stack pointer: %i\n", stackpointer);

    if (n < 2)
        return n;
    else
        return FibonacciNumber(n-1) + FibonacciNumber(n-2);
}

int main () {
    FibonacciNumber(10);
    return 0;
}
0 голосов
/ 13 февраля 2011

Если вам нужно только узнать, был ли изменен стек, вы можете сохранить последний вставленный объект в стеке, взглянуть на него сверху и сравнить два.

0 голосов
/ 13 февраля 2011

EDIT

Прочитайте комментарии. Кажется, невозможно определить направление стека, используя мой метод.

КОНЕЦ РЕДАКТИРОВАНИЯ

Объявление переменной массива в стеке и сравнение адресов последовательных элементов.

#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
    char buf[16];
    printf("&buf[0]: %x\n&buf[1]: %x\n", &buf[0], &buf[1]);  
    return 0;
}

Вывод:

misha@misha-K42Jr:~/Desktop/stackoverflow$ ./a.out 
&buf[0]: d1149980
&buf[1]: d1149981

Итак, стек растет, как и ожидалось.

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