русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Использование стека


Дата добавления: 2014-02-04; просмотров: 1812; Нарушение авторских прав


Передача параметров в подпрограмму

Директива процедуры

 

PROC

ENDP

Эти директивы отмечают начало и конец процедуры. Каждая процедура начинается с директивы PROC и заканчивается директивой ENDP.

Процедуре всегда должен быть предписан один из атрибутов дистанции NEAR(близкая), FAR(дальняя) в качестве операнда директивы PROC.

Процедура с атрибутом NEAR может быть вызвана только из того сегмента команд, где она была определена.

Пример определения процедуры:

 

proc summa near

 

; Тело процедуры

add ax, bx

 

ret

summa endp

 

В данном примере процедура имеет тип NEAR, поэтому для команды RET будут сгенерирован код команды ближнего возврата.

В основной программе процедура summa может быть вызвана с помощью следующего оператора:

 

call summa

 

Имеется возможность косвенного вызова подпрограммы (например, call [si]). Это может оказаться полезным, если организовать в программе массив адресов подпрограмм.

 

 

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

 

 

Стек (stack) — важное понятие теоретического программирования, частный случай линейного списка. Это одномерная динамическая структура данных, добавление элемента в которую (или исключение элемента из которой) производится с одного конца, называемого вершиной стека (Top of Stack). Другими словами, стек организован в виде списка типа LIFO (Last In – First Out – «последний пришел – первый вышел»).

Стек размещается в ОЗУ, в стековом сегменте (т.е. сегментный адрес области памяти для стека хранится в SS). Элементы стека – слова. Нельзя поместить в стек данные размером в байт.



Регистр SP (Stack Pointer – указатель стека) содержит смещение последнего включенного в стек слова, т.е. SP указывает на вершину стека. При включении в стек новых слов вершина перемещается в направлении уменьшения адресов (говорят: стек растет вниз). Включение в стек (push) обозначают стрелкой, направленной вниз ¯, извлечение из стека (pop) — стрелкой, направленной вверх ­. Перечислим команды для работы со стеком:

 

Поместить в стек push src 1) SP ¬ SP – 2 2) (SP) ¬ src
PUSH флаги не изменяются

 

Извлечь из стека pop dst 1) dst ¬ (SP) 2) SP ¬ SP + 2
POP флаги не изменяются

 

Поместить в стек флаги pushf flags¯
PUSH Flags флаги не изменяются

 

Извлечь из стека флаги popf flags­
POP Flags флаги из стека

 

При записи в стек выполняются действия:

– SP:=SP-2;

– вычисление физического адреса памяти по содержимому регистров SS и SP, и запись в него слова.

При выборке из стека выполняются следующие действия:

– из вершины стека считывается слово;

– SP:=SP+2.

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

В 286-м процессоре появились две новые команды для работы со стеком.

Включить в стек все РОНы pusha ax¯ cx¯ dx¯ bx¯ sp¯ bp¯ si¯ di¯
PUSH All флаги не изменяются

В стек помещается то содержимое SP, которое было в нем до выполнения команды pusha.

Извлечь из стека все РОНы popa di­ si­ bp­ sp­ bx­ dx­ cx­ ax­
POP All флаги не изменяются

Эти две команды полезны, когда нужно сохранить и восстановить практически все регистры общего назначения. Если же нужно сохранить и восстановить только два-три регистра, то лучше для каждого из них использовать отдельную команду push и pop.

В ассемблерной программе размер стека задается в описании сегмента стека. Следующий пример иллюстрирует создание стека размером 1024 слова.

StackSG segment para STACK 'Stack'

dw 1024 dup (?)

StackSG Ends

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

За заполнением стека в языках высокого уровня следит специальная система. При возникновении переполнения осуществляется прерывание программы и выдача сообщения 'stack overflow'.

Для правильной работы со стеком количество «погружений» и количество "всплытий" должно быть одинаково, и первой среди стековых команд должна быть команда PUSH.

 

 

Организация подпрограмм

 

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

На первый взгляд для перехода к выполнению подпрограммы можно воспользоваться командой безусловного перехода — ведь код подпрограммы начинается с определенного адреса, к этому адресу и нужно переходить (т.е. помещать его в IP или CS:IP). Но как затем вернуться в вызывающую программу? Ведь подпрограмма может вызываться из разных мест главной программы.

Для организации связи программы и подпрограммы служит пара команд: вызов (call) и возврат (ret — сокращение от return).

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

Когда подпрограмма заканчивает работу, она вызывает инструкцию RET, которая извлекает из стека адрес, занесенный туда соответствующей инструкцией CALL, и заносит его в IP. Это приводит к тому, что вызывающая программа возобновит выполнение с инструкции, следующей за инструкции CALL.

 



<== предыдущая лекция | следующая лекция ==>
 | Команды возврата из подпрограмм


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 2.333 сек.