Почему мы должны очистить стек - PullRequest
1 голос
/ 23 марта 2012

Я беру урок ассемблера, и сейчас мы изучаем стек. Из того, что я узнал, все, что помещено в стек, в конечном итоге должно быть исправлено (очистка стека). Почему нам абсолютно необходимо очистить стек? Я прочитал это, чтобы предотвратить утечки памяти, это так?

Большое спасибо

Ответы [ 6 ]

3 голосов
/ 23 марта 2012

Существует только определенное количество стека для данного потока выполнения.

Его назначение - временно хранить данные, необходимые при вызове функции (например, адрес возврата и параметры, передаваемые в функцию).

Если вы выполните , а не очистите стек при выходе из функции, в конечном итоге вам не хватит места в стеке.

Кроме того, как общее правило, которое выходит за рамки только стека, любой ресурс, используемый вашей программой (пространство стека, пространство кучи, дескриптор файла и т. Д.), Должен храниться как можно меньше времени для повышения общей эффективности.

2 голосов
/ 23 марта 2012

В дополнение к другим ответам большинство используемых мной процессоров поместили адрес возврата из вызова функции в стек.

RET / RTS (или любой другой синтаксис возврата, если он используется для вашего процессора) просто извлекает адрес возврата из стека и устанавливает ПК, ProgramCounter, на этот адрес.

Если функция помещает дополнительные переменные в стек, но не удаляет их, тогда RET возвращает неправильное значение и возвращает неверный адрес, вызывая всевозможные странные действия и / или исключения / ловушки.

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

2 голосов
/ 23 марта 2012

Если вы не очистите стек, как вызывающая функция найдет свои переменные? Вызываемый будет выполняться, выполнять некоторые операции со своими переменными в стеке, а затем возвращаться к вызывающему объекту - что теперь может сделать вызывающий элемент, если указатель стека изменился? Как он может восстановить его, чтобы выяснить, где находятся его собственные переменные стека? Единственный ответ - очистить стек - не имеет значения, кто это делает (вызываемый или вызывающий), но кто-то должен.

Термин «утечка памяти» обычно относится к потере указателя на динамическое выделение памяти, так что вы не можете free() это выделение.

2 голосов
/ 23 марта 2012

Стек - это ограниченный объем памяти, и, как и в любой системе выделения памяти, если вы никогда не очистите ее, она будет просто расти и расти.В конце концов, вы переполните стек, и все чертовски разрушится, когда вы перезапишете другие области памяти или просто сгенерируете неверный адрес.

1 голос
/ 25 марта 2012

Каждая функция может использовать стек, даже если в некоторых программах вы не получите вложенность вызовов функций. One () вызывает два () два вызова, три () и т. Д.

Так что если функция одна имеетлокальные переменные A, B, C в стеке, затем он вызывает две, у двух есть две переменные, которые он использует E и F в стеке.Тогда три имеет G и H в стеке.Если вы не восстановите указатель стека туда, где он был при вводе трех, при возврате к двум он будет думать, что он обращается к E и F, но вместо этого будет обращаться к G и H или к чему-то еще, в зависимости от фрейма стека для трех.() функция.

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

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

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

1 голос
/ 23 марта 2012

Программные подпрограммы (функции) могут совместно использовать стек для получения параметров вызова и возврата переменных, а также запоминания адреса возврата вызывающей стороны.

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

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