Стек: различия между версиями

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
[непроверенная версия][непроверенная версия]
Содержимое удалено Содержимое добавлено
м Область применения: Пример dc добавлен
м checkwiki fixes (1, 2, 9, 17, 22, 26, 38, 48, 50, 52, 54, 64, 65, 66, 76, 81, 86, 88, 89, 101)
 
(не показано 28 промежуточных версий 22 участников)
Строка 1: Строка 1:
{{другие значения}}
{{другие значения}}
[[Файл:Stack preview.png|thumb|400px|Иллюстрация организации стека]]
[[Файл:Stack preview.svg|thumb|400px|Иллюстрация организации стека]]
'''Стек''' ({{lang-en|stack}} — стопка; читается ''стэк'') — [[абстрактный тип данных]], представляющий собой [[Список (информатика)|список элементов]], организованных по принципу ''[[LIFO]]'' ({{lang-en|last in — first out}}, «последним пришёл — первым вышел»).
'''Стек''' ([[МФА]]: ''/stɛk/'') ({{lang-en|stack}} — стопка) — [[абстрактный тип данных]], представляющий собой [[Список (информатика)|список элементов]], организованных по принципу ''[[LIFO]]'' ({{lang-en|last in — first out}}, «последним пришёл — первым вышел»).


Чаще всего принцип работы стека сравнивают со стопкой тарелок: чтобы взять вторую сверху, нужно снять верхнюю.
Чаще всего принцип работы стека сравнивают со стопкой тарелок: чтобы взять вторую сверху, нужно снять верхнюю.
Строка 7: Строка 7:
В [[ЦВК|цифровом вычислительном комплексе]] стек называется магазином — по аналогии с [[Магазин (часть оружия)|магазином в огнестрельном оружии]] (стрельба начнётся с патрона, заряженного последним).
В [[ЦВК|цифровом вычислительном комплексе]] стек называется магазином — по аналогии с [[Магазин (часть оружия)|магазином в огнестрельном оружии]] (стрельба начнётся с патрона, заряженного последним).


В 1946 [[Тьюринг, Алан|Алан Тьюринг]] ввёл понятие стека<ref>{{cite web|url=http://abc.vvsu.ru/Books/ebooks_iskt/Электронныеучебники/Теория%20автоматов/Теор_авт_темы/Машина%20Тьюринга.htm|title=Машина Тьюринга: Введение|accessdate=2013-02-12|archiveurl=|archivedate=}}</ref><ref>{{Книга|ссылка=https://books.google.ru/books?id=MIn1DAAAQBAJ&pg=PT36&lpg=PT36&dq=In+1946,+Alan+Turing+introduced+the+concept+of+stack.&source=bl&ots=-VILFtL-Ju&sig=ACfU3U1A52mE48ZF9P3SVAxvEBzci2QtZQ|автор=Ali Almossawi|заглавие=Bad Choices: How Algorithms Can Help You Think Smarter and Live Happier|год=2017-04-04|издательство=John Murray Press|страниц=140|isbn=978-1-4736-5075-6}}</ref>. А в 1957 году немцы Клаус Самельсон и Фридрих Л. Бауэр запатентовали идею Тьюринга<ref>{{cite web|url=http://worldwide.espacenet.com/publicationDetails/originalDocument?CC=DE&NR=1094019&KC=&FT=E|title=Немецкий патент|accessdate=2013-02-12|archiveurl=http://www.webcitation.org/6ERYlTWAH|archivedate=2013-02-15}}</ref>.
В 1946 [[Тьюринг, Алан|Алан Тьюринг]] ввёл понятие стека<ref>{{cite web|url=http://abc.vvsu.ru/Books/ebooks_iskt/%D0%AD%D0%BB%D0%B5%D0%BA%D1%82%D1%80%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5%D1%83%D1%87%D0%B5%D0%B1%D0%BD%D0%B8%D0%BA%D0%B8/%D0%A2%D0%B5%D0%BE%D1%80%D0%B8%D1%8F%20%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%BE%D0%B2/%D0%A2%D0%B5%D0%BE%D1%80_%D0%B0%D0%B2%D1%82_%D1%82%D0%B5%D0%BC%D1%8B/%D0%9C%D0%B0%D1%88%D0%B8%D0%BD%D0%B0%20%D0%A2%D1%8C%D1%8E%D1%80%D0%B8%D0%BD%D0%B3%D0%B0.htm|title=Машина Тьюринга: Введение|accessdate=2013-02-12|archiveurl=https://web.archive.org/web/20140320172056/http://abc.vvsu.ru/Books/ebooks_iskt/%D0%AD%D0%BB%D0%B5%D0%BA%D1%82%D1%80%D0%BE%D0%BD%D0%BD%D1%8B%D0%B5%D1%83%D1%87%D0%B5%D0%B1%D0%BD%D0%B8%D0%BA%D0%B8/%D0%A2%D0%B5%D0%BE%D1%80%D0%B8%D1%8F%20%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82%D0%BE%D0%B2/%D0%A2%D0%B5%D0%BE%D1%80_%D0%B0%D0%B2%D1%82_%D1%82%D0%B5%D0%BC%D1%8B/%D0%9C%D0%B0%D1%88%D0%B8%D0%BD%D0%B0%20%D0%A2%D1%8C%D1%8E%D1%80%D0%B8%D0%BD%D0%B3%D0%B0.htm|archivedate=2014-03-20|deadlink=no}}</ref><ref>{{Книга|ссылка=https://books.google.ru/books?id=MIn1DAAAQBAJ&pg=PT36&lpg=PT36&dq=In+1946,+Alan+Turing+introduced+the+concept+of+stack.&source=bl&ots=-VILFtL-Ju&sig=ACfU3U1A52mE48ZF9P3SVAxvEBzci2QtZQ|автор=Ali Almossawi|заглавие=Bad Choices: How Algorithms Can Help You Think Smarter and Live Happier|год=2017-04-04|издательство=John Murray Press|страниц=140|isbn=978-1-4736-5075-6|archive-date=2022-08-07|archive-url=https://web.archive.org/web/20220807062146/https://books.google.ru/books?id=MIn1DAAAQBAJ&pg=PT36&lpg=PT36&dq=In+1946,+Alan+Turing+introduced+the+concept+of+stack.&source=bl&ots=-VILFtL-Ju&sig=ACfU3U1A52mE48ZF9P3SVAxvEBzci2QtZQ}}</ref>. А в 1957 году немцы Клаус Самельсон и Фридрих Л. Бауэр запатентовали идею Тьюринга<ref>{{cite web|url=http://worldwide.espacenet.com/publicationDetails/originalDocument?CC=DE&NR=1094019&KC=&FT=E|title=Немецкий патент|accessdate=2013-02-12|archiveurl=https://www.webcitation.org/6ERYlTWAH?url=http://worldwide.espacenet.com/publicationDetails/originalDocument?CC=DE|archivedate=2013-02-15|deadlink=no}}</ref>.


В некоторых языках (например, [[Lisp]], [[Python]]<ref>{{cite web|url=http://www.ibm.com/developerworks/ru/library/l-python_part_3/index.html|title=Python списки: Встроенные функции|accessdate=2013-02-12|archiveurl=http://www.webcitation.org/6ERYlx0vo|archivedate=2013-02-15}}</ref>) стеком можно назвать любой список, так как для них доступны операции pop и push. В языке [[C++]] [[Стандартная библиотека языка C++|стандартная библиотека]] имеет класс с реализованной структурой и методами<ref>{{cite web|url=http://www.cplusplus.com/reference/stack/stack/|title=LIFO stack|accessdate=2013-02-12|archiveurl=http://www.webcitation.org/6ERYmbSlC|archivedate=2013-02-15}}</ref>. И т. д.
В некоторых языках (например, [[Lisp]], [[Python]]<ref>{{cite web|url=http://www.ibm.com/developerworks/ru/library/l-python_part_3/index.html|title=Python списки: Встроенные функции|accessdate=2013-02-12|archiveurl=https://www.webcitation.org/6ERYlx0vo?url=http://www.ibm.com/developerworks/ru/library/l-python_part_3/index.html|archivedate=2013-02-15|deadlink=no}}</ref>) стеком можно назвать любой [[Список (информатика)|список]], так как для них доступны операции pop и push. В языке [[C++]] [[Стандартная библиотека языка C++|стандартная библиотека]] имеет класс с реализованной структурой и методами<ref>{{cite web|url=http://www.cplusplus.com/reference/stack/stack/|title=LIFO stack|accessdate=2013-02-12|archiveurl=https://www.webcitation.org/6ERYmbSlC?url=http://www.cplusplus.com/reference/stack/stack/|archivedate=2013-02-15|deadlink=no}}</ref>. И т. д.


== Программный стек ==
== Программный стек ==


=== Организация в памяти ===
=== {{Anchor|STACK-POINTER}}Организация в памяти ===
[[Файл:Lifo stack.png|thumb|350px|right|Организация стека в виде одномерного упорядоченного по адресам массива. Показаны операции вталкивания и выталкивания данных из стека операциями ''push'' и ''pop''.]]
[[Файл:Lifo stack.svg|thumb|350px|right|Организация стека в виде одномерного упорядоченного по адресам массива. Показаны операции вталкивания и выталкивания данных из стека операциями ''push'' и ''pop''.]]
Зачастую стек реализуется в виде однонаправленного списка (каждый элемент в списке содержит помимо хранимой информации в стеке [[Указатель (тип данных)|указатель]] на следующий элемент стека).
Зачастую стек реализуется в виде однонаправленного списка (каждый элемент в списке содержит помимо хранимой информации в стеке [[Указатель (тип данных)|указатель]] на следующий элемент стека).


Но также часто стек располагается в [[Массив (программирование)|одномерном массиве]] с упорядоченными адресами. Такая организация стека удобна, если элемент информации занимает в памяти фиксированное количество слов, например, 1 слово. При этом отпадает необходимость хранения в элементе стека явного указателя на следующий элемент стека, что экономит память. При этом указатель стека (''Stack Pointer'', — '''SP''') обычно является [[Регистр процессора|регистром процессора]] и указывает на адрес головы стека.
Но также часто стек располагается в [[Массив (программирование)|одномерном массиве]] с упорядоченными адресами. Такая организация стека удобна, если элемент информации занимает в памяти фиксированное количество слов, например, 1 слово. При этом отпадает необходимость хранения в элементе стека явного указателя на следующий элемент стека, что экономит память. При этом указатель стека (''Stack Pointer'', — '''SP''') обычно является [[Регистр процессора|регистром процессора]] и указывает на адрес головы стека.


Предположим для примера, что голова стека расположена по меньшему адресу, следующие элементы располагаются по нарастающим адресам. При каждом вталкивании слова в стек SP сначала уменьшается на 1 и затем по адресу из SP производится запись в память. При каждом извлечении слова из стека (выталкивании) сначала производится чтение по текущему адресу из SP и последующее увеличение содержимого SP на 1.
Предположим для примера, что голова стека расположена по меньшему адресу, следующие элементы располагаются по нарастающим адресам. При каждом вталкивании слова в стек SP сначала увеличивается на 1 и затем по адресу из SP производится запись в память. При каждом извлечении слова из стека (выталкивании) сначала производится чтение по текущему адресу из SP и последующее уменьшение содержимого SP на 1.


При организации стека в виде однонаправленного списка значением переменной стека является указатель на его вершину — адрес вершины. Если стек пуст, то значение указателя равно NULL.
При организации стека в виде однонаправленного списка значением переменной стека является указатель на его вершину — адрес вершины. Если стек пуст, то значение указателя равно NULL.
Строка 26: Строка 26:
<source lang="c">struct stack
<source lang="c">struct stack
{
{
char *data;
void *data;
struct stack *next;
struct stack *next;
};</source>
};</source>


=== Операции со стеком ===
=== Операции со стеком ===
Возможны три операции со стеком: добавление элемента (иначе проталкивание, {{lang-en2|push}}), удаление элемента ({{lang-en2|pop}}) и чтение головного элемента ({{lang-en2|peek}})<ref>{{cite web|url=http://www.rsdn.ru/article/alg/adt/adt.xml|title=Введение|accessdate=2013-02-11|archiveurl=http://www.webcitation.org/6ERYn3XNS|archivedate=2013-02-15}}</ref>.
Возможны три операции со стеком: добавление элемента (иначе проталкивание, {{lang-en2|push}}), удаление элемента ({{lang-en2|pop}}) и чтение головного элемента ({{lang-en2|peek}})<ref>{{cite web|url=http://www.rsdn.ru/article/alg/adt/adt.xml|title=Введение|accessdate=2013-02-11|archiveurl=https://www.webcitation.org/6ERYn3XNS?url=http://www.rsdn.ru/article/alg/adt/adt.xml|archivedate=2013-02-15|deadlink=no}}</ref>.


При проталкивании ({{lang-en2|push}}) добавляется новый элемент, указывающий на элемент, бывший до этого головой. Новый элемент теперь становится головным.
При проталкивании ({{lang-en2|push}}) добавляется новый элемент, указывающий на элемент, бывший до этого головой. Новый элемент теперь становится головным.
Строка 37: Строка 37:
При удалении элемента ({{lang-en2|pop}}) убирается первый, а головным становится тот, на который был указатель у этого объекта (следующий элемент). При этом значение убранного элемента возвращается.
При удалении элемента ({{lang-en2|pop}}) убирается первый, а головным становится тот, на который был указатель у этого объекта (следующий элемент). При этом значение убранного элемента возвращается.


<source lang="cpp">
<source lang="c++">
#include <iostream>
void push( STACK *ps, int x ) // Добавление в стек нового элемента
#include <cassert>
#include <stack> // стандартная реализация стека в C++

int main()
{
{
setlocale(LC_ALL, "");
if ( ps->size == STACKSIZE ) // Не переполнен ли стек?
std::stack<int> stk; // стек элементов типа int

std::wcout << L"Введите целые числа (-1, чтобы закончить ввод):" << std::endl;

while (true)
{
{
int num;
fputs( "Error: stack overflow\n", stderr );
abort();
std::cin >> num;

if (num == -1)
break;

stk.push(num); // добавляем элемент в стек
}
}
else
{
ps->items[ps->size++] = x;
}
}


std::wcout << L"В стеке " << stk.size() << L" элементов" << std::endl;
int pop( STACK *ps ) // Удаление из стека

{
// stk.size() изменяется при добавлении/удалении, поэтому
if ( ps->size == 0 ) // Не опустел ли стек?
// цикл
// for (int i = 0; i < stk.size(); i++) { ... }
// будет вести себя неправильно
for (int i = stk.size(); i > 0; i--)
{
{
// выводим верхний элемент (peek)
fputs( "Error: stack underflow\n", stderr );
std::wcout << L"Верхний элемент: " << stk.top() << std::endl;
abort();

// удаляем верхний элемент
stk.pop();
}
}
else
{
return ps->items[--ps->size];
}
}</source>


assert(stk.empty()); // стек пустой

return 0;
}</source>
=== Область применения ===
=== Область применения ===
Программный вид стека используется для обхода [[Структура данных|структур данных]], например, [[Дерево (теория графов)|дерево]] или [[Граф (математика)|граф]]. При использовании [[Рекурсивные функции|рекурсивных функций]] также будет применяться стек, но его аппаратный вид. Кроме этих назначений, стек используется для организации [[Обратная польская запись|стековой машины]], реализующей вычисления в [[Обратная польская запись|обратной польской записи]]. Примером использования стековой машины является программа Unix [[dc]].
Программный вид стека используется для обхода [[Структура данных|структур данных]], например, [[Дерево (теория графов)|дерево]] или [[Граф (математика)|граф]]. При использовании [[Рекурсивные функции|рекурсивных функций]] также будет применяться стек, но его аппаратный вид. Кроме этих назначений, стек используется для организации [[Обратная польская запись|стековой машины]], реализующей вычисления в [[Обратная польская запись|обратной польской записи]]. Примером использования стековой машины является программа [[Unix]] [[dc]].


Для отслеживания точек возврата из [[Подпрограмма|подпрограмм]] используется стек вызовов.
Для отслеживания точек возврата из [[Подпрограмма|подпрограмм]] используется [[стек вызовов]].


[[Математический сопроцессор|Арифметические сопроцессоры]], [[Программируемый калькулятор|программируемые микрокалькуляторы]] и язык [[Forth]] используют стековую модель вычислений<ref>{{cite web|url=http://savlm.ucoz.ru/publ/10-1-0-47|title=Стек|accessdate=2013-02-12|archiveurl=http://www.webcitation.org/6ERYq9IMI|archivedate=2013-02-15}}</ref>.
[[Математический сопроцессор|Арифметические сопроцессоры]], [[Программируемый калькулятор|программируемые микрокалькуляторы]] и язык [[Forth]] используют стековую модель вычислений<ref>{{cite web|url=http://savlm.ucoz.ru/publ/10-1-0-47|title=Стек|accessdate=2013-02-12|archiveurl=https://www.webcitation.org/6ERYq9IMI?url=http://savlm.ucoz.ru/publ/10-1-0-47|archivedate=2013-02-15|deadlink=no}}</ref>.


Идея стека используется в стековой машине среди [[Стековый язык|стековых языков программирования]].
Идея стека используется в стековой машине среди [[Стековый язык|стековых языков программирования]].
Строка 80: Строка 95:
В [[X86|архитектуре X86]] аппаратный стек — непрерывная область памяти, адресуемая специальными регистрами ESP (указатель стека) и SS (селектор сегмента стека)<ref name=ReferenceA>{{cite web|url=http://dvo.sut.ru/libr/cvti/i618buz/8.htm|title=8.1. Логическая структура памяти программы|accessdate=2013-02-20|archiveurl=https://web.archive.org/web/20121203072017/http://dvo.sut.ru/libr/cvti/i618buz/8.htm|archivedate=2012-12-03|deadlink=yes}}</ref>.
В [[X86|архитектуре X86]] аппаратный стек — непрерывная область памяти, адресуемая специальными регистрами ESP (указатель стека) и SS (селектор сегмента стека)<ref name=ReferenceA>{{cite web|url=http://dvo.sut.ru/libr/cvti/i618buz/8.htm|title=8.1. Логическая структура памяти программы|accessdate=2013-02-20|archiveurl=https://web.archive.org/web/20121203072017/http://dvo.sut.ru/libr/cvti/i618buz/8.htm|archivedate=2012-12-03|deadlink=yes}}</ref>.


До использования стека он должен быть инициализирован так, чтобы регистры SS:ESP указывали на адрес головы стека в области физической оперативной памяти, причём под хранение данных в стеке необходимо зарезервировать нужное количество ячеек памяти (очевидно, что стек в [[Постоянное запоминающее устройство|ПЗУ]], естественно, не может быть организован). Прикладные программы, как правило, от операционной системы получают готовый к употреблению стек. В защищённом режиме работы процессора сегмент состояния задачи содержит четыре селектора сегментов стека (для разных уровней привилегий), но в каждый момент используется только один стек<ref>{{cite web|url=https://math.semestr.ru/inf/memory9.php|title=Стек|accessdate=2013-02-12|archiveurl=|archivedate=}}</ref>.
До использования стека он должен быть инициализирован так, чтобы регистры SS:ESP указывали на адрес головы стека в области физической оперативной памяти, причём под хранение данных в стеке необходимо зарезервировать нужное количество ячеек памяти (очевидно, что стек в [[Постоянное запоминающее устройство|ПЗУ]], естественно, не может быть организован). Прикладные программы, как правило, от операционной системы получают готовый к употреблению стек. В защищённом режиме работы процессора сегмент состояния задачи содержит четыре селектора сегментов стека (для разных уровней привилегий), но в каждый момент используется только один стек<ref>{{cite web|url=https://math.semestr.ru/inf/memory9.php|title=Стек|accessdate=2013-02-12|archiveurl=https://web.archive.org/web/20130101073647/http://math.semestr.ru/inf/memory9.php|archivedate=2013-01-01|deadlink=no}}</ref>.


== Примечания ==
== Примечания ==
Строка 87: Строка 102:


{{Структуры данных}}
{{Структуры данных}}
{{Аспекты операционных систем}}


[[Категория:Стек]]
[[Категория:Стек]]

Текущая версия от 05:48, 14 сентября 2024

Иллюстрация организации стека

Стек (МФА: /stɛk/) (англ. stack — стопка) — абстрактный тип данных, представляющий собой список элементов, организованных по принципу LIFO (англ. last in — first out, «последним пришёл — первым вышел»).

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

В цифровом вычислительном комплексе стек называется магазином — по аналогии с магазином в огнестрельном оружии (стрельба начнётся с патрона, заряженного последним).

В 1946 Алан Тьюринг ввёл понятие стека[1][2]. А в 1957 году немцы Клаус Самельсон и Фридрих Л. Бауэр запатентовали идею Тьюринга[3].

В некоторых языках (например, Lisp, Python[4]) стеком можно назвать любой список, так как для них доступны операции pop и push. В языке C++ стандартная библиотека имеет класс с реализованной структурой и методами[5]. И т. д.

Программный стек

[править | править код]

Организация в памяти

[править | править код]
Организация стека в виде одномерного упорядоченного по адресам массива. Показаны операции вталкивания и выталкивания данных из стека операциями push и pop.

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

Но также часто стек располагается в одномерном массиве с упорядоченными адресами. Такая организация стека удобна, если элемент информации занимает в памяти фиксированное количество слов, например, 1 слово. При этом отпадает необходимость хранения в элементе стека явного указателя на следующий элемент стека, что экономит память. При этом указатель стека (Stack Pointer, — SP) обычно является регистром процессора и указывает на адрес головы стека.

Предположим для примера, что голова стека расположена по меньшему адресу, следующие элементы располагаются по нарастающим адресам. При каждом вталкивании слова в стек SP сначала увеличивается на 1 и затем по адресу из SP производится запись в память. При каждом извлечении слова из стека (выталкивании) сначала производится чтение по текущему адресу из SP и последующее уменьшение содержимого SP на 1.

При организации стека в виде однонаправленного списка значением переменной стека является указатель на его вершину — адрес вершины. Если стек пуст, то значение указателя равно NULL.

Пример реализации стека на языке Си:

struct stack
{
    void *data;
    struct stack *next;
};

Операции со стеком

[править | править код]

Возможны три операции со стеком: добавление элемента (иначе проталкивание, push), удаление элемента (pop) и чтение головного элемента (peek)[6].

При проталкивании (push) добавляется новый элемент, указывающий на элемент, бывший до этого головой. Новый элемент теперь становится головным.

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

#include <iostream>
#include <cassert>
#include <stack> // стандартная реализация стека в C++

int main()
{
    setlocale(LC_ALL, "");
    std::stack<int> stk; // стек элементов типа int

    std::wcout << L"Введите целые числа (-1, чтобы закончить ввод):" << std::endl;

    while (true)
    {
        int num;
        std::cin >> num;

        if (num == -1)
            break;

        stk.push(num); // добавляем элемент в стек
    }

    std::wcout << L"В стеке " << stk.size() << L" элементов" << std::endl;

    // stk.size() изменяется при добавлении/удалении, поэтому
    // цикл 
    //  for (int i = 0; i < stk.size(); i++) { ... }
    // будет вести себя неправильно
    for (int i = stk.size(); i > 0; i--)
    {
        // выводим верхний элемент (peek)
        std::wcout << L"Верхний элемент: " << stk.top() << std::endl;

        // удаляем верхний элемент
        stk.pop();
    }

    assert(stk.empty()); // стек пустой

    return 0;
}

Область применения

[править | править код]

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

Для отслеживания точек возврата из подпрограмм используется стек вызовов.

Арифметические сопроцессоры, программируемые микрокалькуляторы и язык Forth используют стековую модель вычислений[7].

Идея стека используется в стековой машине среди стековых языков программирования.

Аппаратный стек

[править | править код]

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

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

В архитектуре X86 аппаратный стек — непрерывная область памяти, адресуемая специальными регистрами ESP (указатель стека) и SS (селектор сегмента стека)[8].

До использования стека он должен быть инициализирован так, чтобы регистры SS:ESP указывали на адрес головы стека в области физической оперативной памяти, причём под хранение данных в стеке необходимо зарезервировать нужное количество ячеек памяти (очевидно, что стек в ПЗУ, естественно, не может быть организован). Прикладные программы, как правило, от операционной системы получают готовый к употреблению стек. В защищённом режиме работы процессора сегмент состояния задачи содержит четыре селектора сегментов стека (для разных уровней привилегий), но в каждый момент используется только один стек[9].

Примечания

[править | править код]
  1. Машина Тьюринга: Введение. Дата обращения: 12 февраля 2013. Архивировано 20 марта 2014 года.
  2. Ali Almossawi. Bad Choices: How Algorithms Can Help You Think Smarter and Live Happier. — John Murray Press, 2017-04-04. — 140 с. — ISBN 978-1-4736-5075-6. Архивировано 7 августа 2022 года.
  3. Немецкий патент. Дата обращения: 12 февраля 2013. Архивировано 15 февраля 2013 года.
  4. Python списки: Встроенные функции. Дата обращения: 12 февраля 2013. Архивировано 15 февраля 2013 года.
  5. LIFO stack. Дата обращения: 12 февраля 2013. Архивировано 15 февраля 2013 года.
  6. Введение. Дата обращения: 11 февраля 2013. Архивировано 15 февраля 2013 года.
  7. Стек. Дата обращения: 12 февраля 2013. Архивировано 15 февраля 2013 года.
  8. 8.1. Логическая структура памяти программы. Дата обращения: 20 февраля 2013. Архивировано из оригинала 3 декабря 2012 года.
  9. Стек. Дата обращения: 12 февраля 2013. Архивировано 1 января 2013 года.