Эта группа представляет собой набор специализированных команд, ориентированных на организацию гибкой и эффективной работы со стеком.
Стек — это область памяти, специально выделяемая для временного хранения данных программы. Важность стека определяется тем, что для него в структуре программы предусмотрен отдельный сегмент. На тот случай, если программист забыл описать сегмент стека в своей программе, компоновщик tlink выдаст предупреждающее сообщение.
Для стека можно отвести любую область памяти, но ее размер зависит от режима работы микропроцессора и ограничивается 64 Кбайт (или 4 Гбайт в защищенном режиме), а начальный адрес должен быть выровнен на границу параграфа (т.е. д.б. кратным 16).
!!! Даже если сама программа не использует стек, сегмент стека в программе все равно надо описывать. Так как стек программы использует ОС при обработке прерываний, возникающих во время выполнения программы.
Рекомендуемый размер стека (с запасом) - 128 байтов.
В каждый момент времени доступен только один стек, адрес сегмента которого содержится в регистре ss. Этот стек называется текущим. Для того чтобы обратиться к другому стеку (“переключить стек”), необходимо загрузить в регистр ss другой адрес. Регистр ss автоматически используется процессором для выполнения всех команд, работающих со стеком.
|
|
Перечислим еще некоторые особенности работы со стеком:
· запись и чтение данных в стеке осуществляется в соответствии с принципом LIFO (Last In First Out — “последним пришел, первым ушел”);
· по мере записи данных в стек последний растет в сторону младших адресов. Эта особенность заложена в алгоритм команд работы со стеком. Др. словами, стек заполняется снизу вверх: первый элемент записывается в самый конец стека (в ячейку с наибольшим адресом), а следующий элемент записывается «над» ним;
· при чтении из стека первым всегда удаляется верхний элемент, поэтому низ стека фиксирован, а вершина стека все время сдвигается. Текущее положение этой вершины наз. вершиной стека. Адрес вершины стека храниться в регистре SP (stack pointer, указатель стека). Т.е. в регистре SP хранится смещение той ячейки, в которой находится элемент, записанный в стек последним. Смещение относительно начала сегмента стека. Итак, абсолютный адрес вершины стека задается парой сегментов SS:SP. Команды работы со стеком неявно изменяют этот регистр так, чтобы он указывал всегда на последний записанный в стек элемент. Если стек пуст, то значение esp равно адресу последнего байта сегмента, выделенного под стек.
Замечание: Регистр ss автоматически используется процессором для выполнения всех команд, работающих со стеком. Это означает, что при использовании регистров esp/sp и ebp/bp для адресации памяти ассемблер автоматически считает, что содержащиеся в нем значения представляют собой смещения относительно сегментного регистра ss и поэтому префикс SS можно не указывать.
|
|
§ Элементы стека могут иметь любой размер (байт, слово и т.д.). Но команды записи и чтения, предназначенные для стека, работают только со словами, т.е. информация, помещаемая в стек и извлекаемая из него, имеет длину 2 байта.
В общем случае стек организован так, как показано на рис. 2.
Для работы со стеком предназначены три регистра:
· ss — сегментный регистр стека;
· sp/esp — регистр указателя стека;
· bp/ebp — регистр указателя базы кадра стека.
Эти регистры используются комплексно, и каждый из них имеет свое функциональное назначение. Регистр esp/sp всегда указывает на вершину стека, то есть содержит смещение, по которому в стек был занесен последний элемент. Команды работы со стеком неявно изменяют этот регистр так, чтобы он указывал всегда на последний записанный в стек элемент. Если стек пуст, то значение esp равно адресу последнего байта сегмента, выделенного под стек. При занесении элемента в стек процессор уменьшает значение регистра esp, а затем записывает элемент по адресу новой вершины. При извлечении данных из стека процессор копирует элемент, расположенный по адресу вершины, а затем увеличивает значение регистра указателя стека esp. Таким образом, получается, что стек растет вниз, в сторону уменьшения адресов.
Что делать, если нам необходимо получить доступ к элементам не на вершине, а внутри стека? Для этого применяют регистр ebp. Регистр ebp — регистр указателя базы кадра стека. Например, типичным приемом при входе в подпрограмму является передача нужных параметров путем записи их в стек. Если подпрограмма тоже активно работает со стеком, то доступ к этим параметрам становится проблематичным. Выход в том, чтобы после записи нужных данных в стек сохранить адрес вершины стека в указателе кадра (базы) стека — регистре ebp. Значение в ebp в дальнейшем можно использовать для доступа к переданным параметрам.
Начало стека расположено в старших адресах памяти. На рис. 2 этот адрес обозначен парой ss:ffff. Смещение ffff приведено здесь условно. Реально это значение определяется величиной, которую программист задает при описании сегмента стека в своей программе. К примеру:
.data;сегмент данных....stack 256;сегмент стека.codeВ данном фрагменте программы началу стека будет соответствовать пара ss:0100h. Адресная пара ss:ffff — это максимальное для реального режима значение адреса начала стека, так как размер сегмента в нем ограничен величиной 64 Кбайт (0ffffh).