Передача параметров через стек

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

Различают передачу параметра по значению (в стек записывается значение параметра) и по ссылке (в стек записывается адрес переменной-параметра). Чтобы потом можно было обратиться к параметрам процедуры, следует воспользоваться регистром 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. Теоретические сведения

 

Связные списки

Связные списки в языке С создают с помощью структур, в которых одно поле является указателем на следующий элемент списка (односвязный список). Т.е. элемент списка состоит из собственно данных и связующего указателя (указателей). Данные могут быть представлены как в виде набора полей структуры, так и в виде вложенной структуры. Последний вариант представляется предпочтительным, поскольку уменьшает количество параметров в подпрограммах добавления элемента к списку и т.п. Действительно, в подпрограмму необходимо передать все данные для создания нового элемента. Если они объединены в структуру, то для их передачи достаточно одного параметра.

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