Доступ к элементам стека. регистр bp.

      Комментарии к записи Доступ к элементам стека. регистр bp. отключены

Команды PUSH и POP дают доступ только к вершине стека, но иногда необходим доступ к другим, более низким элементам стека. Для этого необходимо использовать косвенную адресацию по регистру-модификатору BP.

Сначала следует записать в BP адрес какого-либо элемента стека, например, вершины:

MOV BP, SP

Теперь команда

MOV AX, [BP]

поместит в AX содержимое последней ячейки стека. Команда

MOV AX, [BP+2]

Поместит в AX содержимое предпоследней ячейки (ее адрес равен адресу вершины стека плюс 2), а команда

MOV AX,[BP+4]

– содержимое третьей с конца ячейки и т.д.

Регистр BP выбран для адресации доступа специально. Регистр SP нельзя использовать, таким образом, т.к. SP не относится к регистрам-модификаторам (т.е. выражение [SP+4] будет ошибкой). Также, если в качестве регистра модификатора используется BP, по умолчанию в качестве сегментного регистра при определении абсолютного физического адреса будет использоваться регистр SS (т.е. в команде его можно не указывать). Если использовать другой регистр модификатор, то регистр SS следует указывать явно, например:

MOV AX, SS:[BX+4]

Таким образом, вариант с регистром BP более удобен.

2.3. Задание на лабораторную работу

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

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

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

Задача должна быть реализована примерно по следующему алгоритму:

– задание строки — арифметического выражения с помощью директивы DB.

– просмотр строки символ за символом и занесение в стек каждой встреченной открывающей скобки.

– если найдена закрывающая скобка, должна быть осуществлена проверка, лежит ли на вершине стека соответствующая открывающая (и было ли внесено в стек, что-либо с момента начала проверки). Если нет – обнаружена некорректность. Если да, то эту открывающую скобку следует удалить из стека.

– после просмотра всей строки обязательно следует проверить не осталась ли в стеке открывающая скобка. Если осталась – обнаружена некорректность.

Кроме того важно, чтобы в момент возврата из программы в ОС (команда RET) стек был точно в том же состоянии, в каком он оказался после выполнения обязательных команд при входе в программу из системы (в стек было отправлено содержимое регистра DS и значение 0).

2.4. Отчет по лабораторной работе

Отчет по лабораторной работе должен содержать:

– текст полученного задания;

– тексты программ с комментариями (в комментариях отобразить изменения содержимого регистров и флагов по ходу выполнения программы).

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

3 .ЛАБОРАТОРНАЯ РАБОТА № 5

ПРОЦЕДУРЫ

3.1. Общие методические указания по выполнению лабораторной работы

Цели работы:

– Знакомство с методами организации процедур в программах на ассемблере.

– Изучение особенностей передачи параметров из основной программы в процедуры.

Среда выполнения:

Интерпретатор команд DOS, ассемблер MASM, интерактивный отладчик AFD.

3.2. Теоретические сведения

3.2.1. Дальние переходы

В предыдущих лабораторных работах рассматривались программы с одним сегментом команд. Однако в общем случае в программе может быть столь много команд, что они не вместятся в один сегмент памяти (их суммарный размер может превзойти 64Кб). В таком случае (либо по какой-то иной причине) в программе описывается несколько сегментов команд, например:

Cl SEGMENT

ASSUME CS: Cl, …

START: MOV AX, 0

JMP FAR PTR L ;goto L

Cl ENDS

C2 SEGMENT

ASSUME CS: C2

L: INC BX

C2 ENDS

В начале каждого сегмента команд должна быть указана директива ASSUME, в которой (помимо прочего) сегментному регистру CS ставится в соответствие данный сегмент (именно по этой информации ассемблер узнает, что текущий сегмент является сегментом команд). В противном случае, встретив первую же метку, ассемблер зафиксирует ошибку.

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

Если меняется только IP, то это означает переход внутри сегмента. Такие переходы называются близкими или внутрисегментными. Но если в программе имеется несколько сегментов команд, тогда возникает потребность в переходах из одного такого сегмента в другой (например, из сегмента О на метку L сегмента С2). Такие переходы называются дальними или межсегментными. При этих переходах меняется значение и регистра CS, и регистра IP: CS устанавливается на начало сегмента с меткой (CS:=C2), а в IP записывается смещение метки внутри ее сегмента (IP:=offset L).

Существуют два варианта дальнего перехода: прямой и косвенный (но и в том и в другом случае переход всегда является безусловным).

Команда прямого перехода записывается следующим образом:

JMP FAR PTR

Слово FAR (дальний) указывает ассемблеру, что метка дальняя, что она находится в другом сегменте команд. По этой команде регистр CS устанавливается на начало того сегмента, в котором эта метка находится, а в регистр IP записывается смещение этой метки внутри данного сегмента:

CS:=seg ; IP:=offset

Так, в примере, приведенном выше, указан дальний переход на метку L.

Команда дальнего косвенного перехода записывается следующим образом:

JMP

В этой команде указывается адрес двойного слова, в котором должен находиться абсолютный адрес перехода в виде адресной пары seg:ofs, записанной в перевернутом виде: смещение ofs должно быть записано в два младших байта двойного слова, а номер сегмента seg – в два старших байта. Команда делает переход по этому абсолютному адресу, т. е. записывает в регистр CS величину seg, а в регистр IP — величину ofs:

CS:= [двойное слово+2]; IP:= [двойное слово]

Пример:

X DD L ;X:offset L, X+2:seg L

JMP X ;goto L(CS:=seg L,IP:=offset L)

Имя X, указанное в команде, должно быть описано заранее, чтобы ассемблер, встретив команду перехода, интерпретировал X как двойное слово. В противном случае, следует явно указать, что имя обозначает переменную размером в двойное слово. Для этого используется оператор PTR:

JMP DWORD PTR X

3.2.2. Подпрограммы (процедуры)

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

Размещение подпрограммы

Обычно подпрограммы (п/п) размещают либо в конце сегмента команд за командой FINISH (см. рисунок а), либо в самом начале этого сегмента — перед той командой, с которой должно начинаться выполнение программы (см. рисунок б). В больших программах подпрограммы нередко размещают в отдельном сегменте команд (см. рисунок в).

Варианты размещения подпрограммы в тексте программы

Оформление подпрограммы

Описание подпрограммы в виде процедуры выглядит так:

PROC

ENDP

Перед телом процедуры (ее командами) ставится директива PROC (procedure), а за ним — директива ENDP (end of procedure). В обеих этих директивах указывается одно и то же имя — имя, присвоенное процедуре.

У директивы PROC есть параметр — это либо NEAR (близкий), либо FAR (дальний). Параметр может и отсутствовать, тогда считается, что он равен NEAR (в связи с этим параметр NEAR обычно не указывается). При параметре NEAR или при отсутствии параметра процедура называется близкой, при параметре FAR — дальней. К близкой процедуре можно обращаться только из того сегмента команд, где она описана, и нельзя обращаться из других сегментов, а к дальней процедуре можно обращаться из любых сегментов команд (в том числе и из того, где она описана). В этом и только в этом различие между близкими и дальними процедурами.

Статьи к прочтению:

Jessie J — Price Tag ft. B.o.B


Похожие статьи:

  • Доступ к элементам массива

    Массивы и кортежи • Простые массивы • Многомерные массивы • Зубчатые массивы • Класс Array • Массивы в качестве параметров • Перечисления • Кортежи •…

  • Использование стека для передачи параметров

    Стек часто используется при обращении к процедурам для передачи параметров в процедуры. При передаче управления процедуре процессор автоматически…