Память с произвольным доступом, безусловно, хороша, особенно для микропроцессоров, но иногда удобнее использовать запоминающее устройство, доступ к которому осуществляется непроизвольно и непоследовательно. Допустим, вы работаете в офисе, и сотрудники подходят к вашему столу, чтобы дать задание. Выполнение каждого из них предполагает использование папки с документами. Часто при работе над одним заданием вы обнаруживаете, что не можете продолжать, пока не выполните определенную задачу, используя другую папку. Так что поверх первой папки вы кладете вторую и работаете с ней. Затем вам дают еще одно задание, более приоритетное, чем предыдущее, и вы кладете новую папку поверх двух других. Для выполнения этого вам требуется еще одна папка с документами. И вот на вашем столе уже целая стопка из четырех папок.
Это упорядоченный способ хранения и отслеживания всех выполняемых заданий. Самая верхняя папка всегда соответствует приоритетной задаче. После окончания работы с этой папкой вы переходите к следующей. Когда наконец вы разберетесь с последней папкой на своем столе (с той, с которой начали), сможете отправиться домой.
Технически такая форма хранения данных называется «
Компьютеры также могут использовать стек, но не для хранения заданий, а для хранения чисел, что удобно. Добавление элемента в стек называется вталкиванием (push), а его удаление — выталкиванием (pop).
Предположим, вы пишете программу на языке ассемблера, в которой используются регистры A, B и C. На каком-то этапе программе требуется выполнить еще один небольшой расчет, также предполагающий применение регистров A, B и C. В итоге нужно вернуться к тому, что вы делали раньше, и продолжить использовать регистры A, B и C с теми значениями, которые в них хранились.
Безусловно, вы можете просто сохранить значения регистров A, B и C в других ячейках памяти, а затем загрузить их оттуда обратно. Однако тогда нужно будет следить за содержимым ячеек памяти. Более удобный способ — помещение (вталкивание) значений регистров в стек.
PUSH A
PUSH B
PUSH C
Я объясню, как работают эти команды, чуть позже. Пока достаточно понять, что они каким-то образом сохраняют содержимое регистров в памяти LIFO. После выполнения этих команд ваша программа может спокойно использовать эти регистры для других целей. Чтобы вернуть предыдущие значения, вы просто выталкиваете элементы из стека в обратном порядке.
POP C
POP B
POP A
Помните: последний помещенный в стек элемент удаляется из него в первую очередь. Случайное изменение порядка команд POP приведет к ошибке.
Преимущество стека в том, что его могут использовать разные разделы программы, не вызывая проблем. Например, после помещения в стек значений регистров A, B и C другому разделу программы может понадобиться сделать то же самое с регистрами C, D и E.
PUSH C
PUSH D
PUSH E
Для восстановления значения регистров используются команды РОР.
POP E
POP D
POP C
После их выполнения из стека будут извлечены значения регистров C, B и A.
Как реализуется стек? Прежде всего, это просто раздел памяти, не используемый для хранения каких-либо других данных. Для обращения к этому разделу памяти микропроцессор 8080 предусматривает специальный 16-битный регистр, который называется
Приведенные выше примеры добавления и удаления элементов из стека не вполне точно демонстрируют работу микропроцессора 8080. Команда 8080 PUSH фактически сохраняет в стеке 16-битные значения, а команда POP извлекает их. Именно поэтому вместо таких команд, как PUSH C и POP C, используем следующие восемь.
Код
Команда
Код
Команда
C5
PUSH BC
C1
POP BC
D5
PUSH DE
D1
POP DE
E5
PUSH HL
E1
POP HL
F5
PUSH PSW
F1
POP PSW
Команда PUSH BC сохраняет в стеке значения регистров B и C, а команда POP BC извлекает их. Аббревиатура PSW в последней строке означает
PUSH PSW
PUSH BC
PUSH DE
PUSH HL
Когда вам потребуется восстановить содержимое этих регистров, обращайтесь к командам POP в обратном порядке.
POP HL
POP DE
POP BC
POP PSW
Как работает стек? Предположим, что указатель стека равен 8000h. При выполнении команды PUSH BC происходит следующее:
значение указателя стека уменьшается на 1 и становится равным 7FFFh;
содержимое регистра B сохраняется по адресу, соответствующему значению указателя стека, то есть в ячейке 7FFFh;
значение указателя стека уменьшается на 1 и становится равным 7FFEh;