Передача параметров через стек
Существует еще один способ передачи параметров: вызывающая программа должна перед вызовом процедуры записать параметры в стек.
Различают передачу параметра по значению (в стек записывается значение параметра) и по ссылке (в стек записывается адрес переменной-параметра). Чтобы потом можно было обратиться к параметрам процедуры, следует воспользоваться регистром BP (сначала передать в BP адрес вершины стека, а затем использовать выражения вида [BP+i] для доступа к параметрам процедуры). Но сначала надо сохранить значение регистра BP в стеке, чтобы после окончания работы процедуры восстановить его обратно.
В конце работы процедура должна удалить параметры из стека. Для этого в команду RET добавляется числовой параметр, указывающий, сколько байтов надо удалить из стека (если параметр не указывается, то команда воспринимается как RET 0, т.е. возврат из процедуры без очистки стека).
RET 2*k ;удаление k параметров
Пример. Создать процедуру обнуления n байтов памяти по адресу X. Параметры передаются через стек.
S SEGMENT STACK ; Сегмент стека
DB 200 DUP(0ABh)
S ENDS
D SEGMENT ; Сегмент данных
X DB 20 DUP (1)
Y DB 10 DUP (2)
D ENDS
CODE SEGMENT ; Сегмент кода
ASSUME SS:S,CS:Code, DS:D
; Процедура обнуления n байтов памяти по заданному
; адресу. Параметры передаются через стек.
NUL PROC
PUSH BP; ; Сохранение значения
; регистра BP
MOV BP, SP ; Установка в BP
;адреса вершины стека
PUSH BX ; Сохранение текущих значений
PUSH CX ; регистров BX и CX
; Извлечение из стека параметров процедуры
; в обратном порядке
MOV CX, [BP+4] ; CX:=N (второй параметр – число
; байтов – в счетчик цикла)
MOV BX, [BP+6] ; (первый параметр – адрес массива
; байтов – в регистр-модификатор
; для косвенной адресации)
L1: MOV BYTE PTR [BX], 0 ; обнуление байта
;по адресу из BX (т.е. обнуление текущего
;элемента массива)
INC BX
LOOP L1 ; Окончание тела цикла
POP CX ; Восстановление значений
POP BX ; регистров BX и CX,
POP BP ; а также регистра BP
RET 4 ; Возврат из процедуры с
; очищением стека от параметров
NUL ENDP ; Окончание процедуры
; Основная программа
MMM PROC FAR
; Выполнение на входе соглашений DOS
PUSH DS ; Запись содержимого DS в стек
SUB AX,AX ; Запись ноля
PUSH AX ; в стек
; Установка верного значения в регистре DS.
; Регистры CS и SS устанавливаются системой.
MOV AX,D ; Занесение адреса
MOV DS,AX ; D в DS
; Обнуление 20 байт по адресу X
LEA AX, X
PUSH AX ; Передача в стек 1-го параметра
; процедуры – адреса памяти,
; которую нужно очистить
MOV AX, 20
PUSH AX ; Передача в стек 2-го параметра
; процедуры – размера очищаемой
; области памяти в байтах
CALL NUL ; вызов
; Обнуление 10 байт по адресу Y
LEA AX, Y
PUSH AX ; Передача в стек 1-го параметра
; процедуры
MOV AX, 10
PUSH AX ; Передача в стек 2-го параметра
; процедуры
CALL NUL
RET ;Возврат в DOS
MMM ENDP
CODE ENDS ;Конец сегмента кода
END MMM ;Конец программы
3.3. Задание на лабораторную работу
1) Изучить и выполнить программы-примеры из теоретического введения к лабораторной работе. Проследить за использованием стека и регистров для передачи управления и параметров.
2) Написать и выполнить программу, реализующую работу с процедурами сообразно своему варианту из табл. 5. Программа должна быть реализована в двух вариантах:
– передача параметров в процедуру осуществляется через регистры;
– передача параметров в процедуру осуществляется через стек.
Таблица 5
Варианты заданий на лабораторную работу
№ вар. | Задание |
Даны массивы P (10 байт) и Q (7 байт). Найти количество положительных элементов в обоих массивах. Подсчет количества положительных элементов оформить как процедуру. | |
Даны массивы X (5 слов) и Y (6 слов). Найти количество элементов, равных 0, в обоих массивах. Подсчет количества нулей оформить как процедуру. | |
Даны массивы J (7 байт) и В (5 байт). Заменить все отрицательные элементы в массивах на -1, положительные – на 1. Замену элементов оформить как процедуру. | |
Даны массивы M (6 байт) и Т (7 байт), заполненные различными символами. Заменить все символы «*» в массивах на «#». Замену элементов оформить как процедуру. |
Продолжение табл. 5
Даны массивы R (6 байт) и Т (7 байт), заполненные различными символами. Подсчитать количество символов «!» в обоих массивах. Подсчет символов оформить как процедуру. | |
Даны массивы A (5 слов) и B (4 слова). Найти сумму всех положительных элементов каждого массива. Подсчет суммы элементов оформить как процедуру. | |
Даны массивы E (7 слов) и F (5 слов). Найти количество четных элементов в каждом массиве. Подсчет количества четных элементов оформить как процедуру. | |
Даны массивы I (7 слов) и J (5 слов). Заменить все нечетные элементы на 0 в каждом массиве. Замену нечетных элементов оформить как процедуру. | |
Даны массивы I (6 слов) и J (7 слов). Найти сумму всех нечетных элементов массивов. Подсчет суммы элементов оформить как процедуру. | |
Даны массивы L (10 байт) и M (7 байт), заполненные различными символами. Определить количество слов (слово - группа символов, не содержащая других пробелов внутри себя и отделенная от других символов пробелами) в каждом массиве. Подсчет количества слов оформить как процедуру. | |
Даны массивы T (8 байт) и U (7 байт). Определить минимальный положительный элемент в каждом массиве. Поиск элемента оформить как процедуру. | |
Даны массивы A (6 слов) и B (7 слов). Определить максимальный отрицательный элемент в каждом массиве. Поиск элемента оформить как процедуру. |
Дополнительное задание (по желанию). Реализовать переход на процедуру и возврат из нее без использования команд CALL и RET (используя PUSH, POP, JMP).
3) Выполнить индивидуальное задание, которое рассматривается в качестве зачетной работы по всему курсу ассемблера (задание выдается преподавателем).
Примеры зачетных заданий
Задание 1. Дано:
X, Y – массивы по 3 восьмибитовых числа со знаком;
SUM – 16-битовая переменная.
В каждом массиве найти среднее по величине число (не среднее значение, а среднее из трех по величине), вычислить сумму двух полученных чисел и поместить ее в переменную SUM.
Определение среднего из трех чисел оформить в виде процедуры. Параметры передать через регистры AL, AH и BL. Результат вернуть через регистр BH.
Задание 2. Дано:
три массива чисел-слов без знака: X – 20 чисел, Y – 30 чисел, Z – 16 чисел;
SUM – переменная – двойное слово.
Найти максимум в каждом из массивов, а затем вычислить сумму этих максимумов. Полученную сумму поместить в переменную SUM.
Вычисление максимума оформить в виде процедуры. Параметры передать через стек. Результат вернуть в регистре DX.
Задание 3. Дано:
X, Y – массивы по 3 восьмибитовых числа со знаком;
SUM – 16-битовая переменная.
В каждом массиве найти среднее по величине число (не среднее значение, а среднее из трех по величине), вычислить сумму двух полученных чисел и поместить ее в переменную SUM.
Определение среднего из трех чисел оформить в виде процедуры. Параметры передать через стек. Результат вернуть через регистр AL.
Задание 4. Дано:
три массива чисел-слов без знака: X – 20 чисел, Y – 30 чисел, Z – 16 чисел;
SUM – переменная – двойное слово.
Найти максимум в каждом из массивов, а затем вычислить сумму этих максимумов. Полученную сумму поместить в переменную SUM.
Вычисление максимума оформить в виде процедуры. Параметры передать через регистры. Результат вернуть в регистре DX.
3.4. Отчет по лабораторной работе
Отчет по лабораторной работе должен содержать:
– тексты полученных заданий с номером варианта;
– тексты программ с комментариями (в комментариях отобразить изменения содержимого регистров и флагов по ходу выполнения программы).
Кроме отчета и демонстрации работающих программ студент отвечает на вопросы по теоретической части, относящейся к данной лабораторной работе.
4. ЛАБОРАТОРНАЯ РАБОТА №6.
ИСПОЛЬЗОВАНИЕ СВЯЗНЫХ СПИСКОВ ДЛЯ УПРАВЛЕНИЯ ПАМЯТЬЮ И ПРОЦЕССАМИ
4.1. Общие методические указания по выполнению лабораторной работы
Цели работы:
– освежить и углубить навыки работы с динамическими списками, широко используемыми в ОС для реализации механизмов управления процессами и ресурсами.
– закрепить полученные в рамках лекционного курса знания об используемых ОС алгоритмах, реализуемых на базе динамических связных списков.
– разработать модуль, реализующий работу со связным списком, лежащим в основе заданного преподавателем алгоритма управления ресурсом или процессами.
– разработать оконное приложение, реализующее заданный алгоритм и демонстрирующее работоспособность модуля.
– получить опыт распределения работы по разработке программы между членами рабочей группы (предполагается выполнение одного задания группами по 2-3 человека).
Среда разработки:
Visual C++.
Перед выполнением работы необходимо повторить следующие темы лекционных курсов «Операционные системы» и «Программирование на языках высокого уровня»:
– дисциплины выбора свободного участка памяти при распределении памяти динамическими разделами («первый подходящий», «самый подходящий», «самый неподходящий»).
– диспетчеризацию задач с использованием статических приоритетов, в т.ч. относительных и абсолютных.
– дисциплины диспетчеризации FCFS, SJN, SRT, RR, RR + статические относительные приоритеты.
– работу с указателями и динамическим выделением памяти.
– понятие линейного списка, в том числе последовательного и связного списков.
– реализация списков с использованием статических (последовательные списки) и динамических (связные списки) структур данных.
– понятия стека, очереди, односвязных, двусвязных и циклических списков. Их реализация на языке программирования C.
4.2. Теоретические сведения
Связные списки
Связные списки в языке С создают с помощью структур, в которых одно поле является указателем на следующий элемент списка (односвязный список). Т.е. элемент списка состоит из собственно данных и связующего указателя (указателей). Данные могут быть представлены как в виде набора полей структуры, так и в виде вложенной структуры. Последний вариант представляется предпочтительным, поскольку уменьшает количество параметров в подпрограммах добавления элемента к списку и т.п. Действительно, в подпрограмму необходимо передать все данные для создания нового элемента. Если они объединены в структуру, то для их передачи достаточно одного параметра.
В списке могут храниться как сами записи-данные, так и только указатели на них. Второй вариант является самым гибким и мощным, поскольку, во-первых, уменьшает объем информации, передаваемый в подпрограммы и обратно (передаем не саму запись с данными, а только указатель на нее), а во-вторых, позволяет включать одну и ту же запись одновременно в несколько списков.