- •1.2.2. Команды управления циклом
- •1.2.3. Работа с массивами
- •1.3. Задание на лабораторную работу
- •1.4. Отчет по лабораторной работе
- •2. Лабораторная работа № 4
- •2.1. Общие методические указания по выполнению лабораторной работы
- •2.2. Теоретические сведения
- •2.2.1. Стек и сегмент стека
- •2.2.2. Стековые команды
- •2.2.3 Приемы работы со стеком
- •2.3. Задание на лабораторную работу
- •2.4. Отчет по лабораторной работе
- •3 .Лабораторная работа № 5
- •3.1. Общие методические указания по выполнению лабораторной работы
- •3.2. Теоретические сведения
- •3.2.1. Дальние переходы
- •3.2.2. Подпрограммы (процедуры)
- •3.3. Задание на лабораторную работу
- •3.4. Отчет по лабораторной работе
- •4. Лабораторная работа № 6
- •4.1. Общие методические указания по выполнению лабораторной работы
- •4.2. Теоретические сведения
- •4.2.1. Общие сведения о процессах и потоках
- •4.2.2. Описание свойств и методов компонента StringGrid
- •4.2.3. Получение информации о процессах и потоках
- •4.3.Задание на лабораторную работу
- •4.4. Отчет по лабораторной работе
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