 |
::
Меню :: |
 |
|
|
 |
::
Друзі :: |
 |
|
|
 |
::
Лічильники :: |
 |
|
|
|
Стік
Стеком називають область
програми для тимчасового
зберігання довільних даних. Зрозуміло, дані можна зберігати і в
сегменті даних, проте в цьому випадку для того, що кожного зберігається на
час даного треба заводити окремий іменований елемент пам'яті, що збільшує розмір
програми і кількість використовуваних імен. Зручність стека полягає в
тому, що його область використовується багато разів, причому збереження в стеку даних
і вибірка їх звідти виконується за допомогою ефективних команд push і pop без
вказівки яких-небудь імен.
Стек традиційно використовується, наприклад, для збереження вмісту
регістрів, використовуваних програмою, перед викликом підпрограми, яка, у свою
чергу, використовуватиме регістри процесора "в своїх особистих цілях". Початковий
вміст регістрів витягується із стека після повернення з підпрограми. Інший
поширений прийом - передача підпрограмі потрібних нею параметрів через
стек. Підпрограма, знаючи, в якому порядку поміщені в стек параметри, може забрати
їх звідти і використовувати при своєму виконанні.
Відмітною
особливістю стека є своєрідний порядок вибірки що містяться
в нім даних: у будь-який момент часу в стеку доступний тільки верхній елемент,
тобто елемент, завантажений в стек останнім. Вивантаження із стека верхнього елементу
робить доступним наступний елемент.
Елементи стека
розташовуються в області пам'яті, відведеної під стек, починаючи з дна
стека (тобто з його максимальної адреси) по адресах, що послідовно зменшуються.
Адреса верхнього, доступного елементу зберігається в регістрі-покажчику стека SP.
Як і будь-яка інша область пам'яті програми, стек повинен входити в якийсь сегмент
або утворювати окремий сегмент. У будь-якому випадку сегментна адреса цього
сегменту поміщається в сегментний регістр стека SS.
Таким чином, пара регістрів
Ss:sp описують адресу доступного осередку стека: у SS зберігається сегментна адреса
стека, а в SP - зсув останнього збереженого в стеку даного (мал. 1.10,
а). Звернете увагу на те, що в початковому стані покажчик стека SP
указує на осередок, що лежачий під дном стека і не входить в нього.

Мал. 1.10.
Організація
стека:
а - початковий стан, би - після завантаження одного елементу (у даному прикладі
- вмісту регістра АХ) у - після завантаження другого елементу (вмісту
регістра DS) грам - після вивантаження одного елементу д - після вивантаження двох елементів
і повернення в початковий стан.
Завантаження в стек здійснюється
спеціальною командою роботи із стеком push (проштовхнути). Ця команда спочатку
зменшує на 2 вміст покажчика стека, а потім поміщає операнд за адресою
в SP. Якщо, наприклад, ми хочемо тимчасово зберегти в стеку вміст регістра
АХ, слід виконати команду
push АХ
Стек переходить в стан,
показаний на мал. 1.10, би. Видно, що покажчик стека зміщується на два байти
вгору (у бік менших адрес) і за цією адресою записується вказаний в
команді проштовхування операнд. Наступна команда завантаження в стек, наприклад
push DS
переведе стек в
стан, показаний на мал. 1.10, ст. У стеку тепер зберігатимуться два елементи, причому
доступним буде тільки верхній, на який указує покажчик стека
SP. Якщо
через якийсь час нам знадобилося відновити початковий вміст збережених
в стеку регістрів, ми повинні виконати команди вивантаження із стека pop (виштовхнути):
pop DS
pop AX
Стан стека після виконання першої
команди показаний на мал. 1.10, грам, а після другої - на мал. 1.10, д. Для правильного
відновлення вмісту регістрів вивантаження із стека повинне виконуватися в
порядку, строго протилежному завантаженню, - спочатку вивантажується елемент, завантажений останнім,
потім попередній елемент і так далі
Зовсім не обов'язково при відновленні даних поміщати їх туди, де вони були
перед збереженням. Наприклад, можна помістити в стек вміст
DS, а витягувати
його звідти в інший сегментний регістр - ES;
push DS
pop ES ; Тепер Es=ds, а стек порожній
Це поширений прийом
для перенесення вмісту одного регістра в іншій, особливо, якщо другий
регістр - сегментний.
Звернете
увагу (див. рис 1.10) на те, що після вивантаження збережених в стеку даних
вони фізично не стерлися, а залишилися в області стека на своїх місцях. Правда,
при "стандартній" роботі із стеком вони виявляються недоступними. Дійсно,
оскільки покажчик стека SP указує під дно стека, стек вважається за
порожній; чергова команда push помістить нове дане на місце збереженого раніше
вмісту АХ, затерев його. Проте поки стек фізично не затертий, збереженими
і вже вибраними з нього даними можна користуватися, якщо пам'ятати, в якому порядку
вони розташовані в стеку. Цей прийом часто використовується при роботі з підпрограмами.
Якого розміру
має бути стек? Це залежить від того, наскільки інтенсивно він використовується в
програмі. Якщо, наприклад, планується зберігати в стеку масив об'ємом 10
000 байт, то стек має бути не менше цього розміру. При цьому треба мати на
увазі, що у ряді випадків стек автоматично використовується системою, зокрема, при виконанні
команди переривання int 21h. По цій команді спочатку процесор поміщає в
стек адресу повернення, а потім DOS відправляє туди ж вміст регістрів і іншу
інформацію, що відноситься до перерваної програми. Тому, навіть якщо
програма зовсім не використовує стек, він все ж таки має бути присутнім
в програмі і мати розмір не менше декількох десятків слів. У нашому першому
прикладі ми відвели під стек 128 слів, що безумовно достатньо.
-
|
 |
::
Наша кнопка :: |
 |
|
 |
Отримати код:
|
Підтримайте наш сайт і розмістіть нашу
кнопку на своєму ресурсі. |
|
|
 |
::
Популярне :: |
 |
|
|
 |
:: Посилання :: |
 |
|
|
|