Uploaded by Елизавета Звегинцева

ОЭВМ 6л

advertisement
МИНОБРНАУКИ РОССИИ
САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ
ЭЛЕКТРОТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
«ЛЭТИ» ИМ. В.И. УЛЬЯНОВА (ЛЕНИНА)
Кафедра МОЭВМ
ОТЧЕТ
по лабораторной работе № 6
по дисциплине «Организация ЭВМ и систем»
ТЕМА: Организация связи Ассемблера с ЯВУ на примере программы
построения частотного распределения попаданий псевдослучайных
целых чисел в заданные интервалы
Студентка гр. 8381
Звегинцева Е.Н.
Преподаватель
Кирьянчиков В. А.
Санкт-Петербург
2019
Цель работы:
Получить практические навыки программирования на языке Ассемблера.
Формулировка задания:
На языке высокого уровня программируется ввод с клавиатуры и контроль
исходных данных (см.ниже), а также генерируется массив псевдослучайных целых
чисел, изменяющихся в заданном диапазоне и имеющих равномерное или
гауссовское (ограниченное интервалом [Mx-3*S,Mx+3*S]) распределение.
Следует привести числа к целому виду с учетом диапазона изменения. Далее
должны вызываться 1 или 2 ассемблерных процедуры для формирования
распределения количества попаданий псевдослучайных целых чисел в заданные
интервалы. Ассемблерные процедуры должны вызываться как независимо
скомпилированные модули.
Передача параметров в процедуру должна
выполняться через кадр стека.
Результирующий массив частотного распределения чисел по интервалам,
сформированный на ассемблерном уровне, возвращается в программу,
реализованную на ЯВУ, и затем сохраняется в файле и выводится на экран
средствами ЯВУ.
Исходные данные:
1. Длина массива псевдослучайных целыхчисел - NumRanDat (<= 16K)
2. Диапазон изменения массива псевдослучайных целых чисел
[Xmin, Xmax] (м.б. биполярный, например, [-100, 100])
3. Массив псевдослучайных целых чисел.
4. Количество интервалов, на которые разбивается диапазон
изменения массива псевдослучайных целых чисел - NInt ( <=24 )
5. Массив левых границ интервалов разбиения LGrInt
(должны принадлежать интервалу [Xmin,Xmax])
В общем случае интервалы разбиения диапазона изменения псевдослучайных
чисел
могут иметь различную длину.
7 вариант:
Для бригад с нечетным номером: программа формирования распределения количества попаданий псевдослучайных целых чисел в заданные
интервалы реализуется в виде одного асемблерного модуля (процедуры),
сразу получающего требуемое распределение и возвращающего его в
головную программу, написанную на ЯВУ;
Результаты:
1. Обязательный - текстовая таблица, строка которой содержит:
- номер интервала,
- левую границу интервала,
- количество псевдослучайных чисел, попавших в интервал.
Количество строк должно быть равно числу интервалов разбиения.
Таблица должна выводиться на экран и сохраняться в файле.
Тестирование:
Размер
массива
псевдосл.
чисел
Диапазон
[Xmin,Xmax]
10
[-5;5]
5
[-2;2]
Массив
псевдослучайных
чисел
1) 3
2) 4
3) 4
4) -4
5) 2
6) 0
7) 0
8) 5
9) -4
10) -5
1) -1
2) 0
3) 2
4)-2
5) 2
Массив
левых
границ
Результирующий
массив
частотного
распределения
1) -5
2) -3
3) 3
(-5) 3
(-3) 3
(3) 4
1) -2
2) 0
(-2) 2
(0) 3
15
[-5;10]
1) 4
2) -2
3) 9
4) -1
5) -4
6) 7
7) 1
8) 9
9) -3
10) -5
11) 4
12) -4
13) -4
14) 6
15) 4
1) -5
2) -2
3) 2
4) 7
(-5)
(-2)
(2)
(7)
5
3
4
3
Вывод: В ходе выполнения данной лабораторной работы была написана
программа на языке Ассемблера, которая строит частотное распределение
попаданий псевдослучайных чисел в заданные интервалы.
В результате выполнения лабораторной работы были получены практические
навыки программирования на языке Ассемблер.
Приложения А. Исходный код
LR6_ASM.cpp
#include "stdafx.h"
#include "iostream"
#include <iomanip>
using namespace std;
extern "C" { //подключение файла с кодом ассемблера
void func (int *arr, int Xmin, int *res, int length_);
void func2(int *result, int *LGr, int* result_final, int legth_big, int Xmin, int
length_);
void func2_1(int *result, int *LGr, int *result_final, int length_big, int Xmin,
int lehtg_);
}
void sort(int *arr, int count_)
{
for (int i = 0; i < count_ - 1; i++) {
for (int j = 0; j < count_ - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int b = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = b;
}
}
}
}
void print(int*arr, int count_)
{
cout << endl << endl;
for (int j = 0; j < count_; j++) {
cout << j + 1 << ". " << arr[j] << "\n";
}
}
void print_task(int*arr, int* LGr, int count_)
{
cout << endl << endl;
cout << "Номер интервала\t Левая граница интервала
интервал\n";
for (int j = 0; j < count_; j++) {
cout << j + 1 << "\t\t ("<<LGr[j]<<")\t\t\t
}
}
Кол-во чисел, попавших в
" << arr[j] << "\n";
int main()
{
setlocale(0, "RUS");
int length_; //длина массива псевдослучайных чисел
do {
cout << "Введите длину массива псевдослучайных чисел\n";
cin >> length_;
} while ( (length_ > 16000) || (length_ <0) );
int Xmin, Xmax; //левая и правая границы диапазона изменения массива
do {
cout << "Введите минимальное значение отрезка\n";
cin >> Xmin;
cout << "Введите максимальное значение отрезка\n";
cin >> Xmax;
} while (Xmin > Xmax);
int *arr = new int[length_]; //массив псевдослучайных чисел
for (int i = 0; i < length_; i++) {
arr[i] = Xmin + rand() % (Xmax-Xmin+1);
};
cout << "Массив псевдослучайных чисел:\n";
print(arr, length_);
int *result = new int[(Xmax - Xmin + 1)]; //массив полученного распределения
int *LGr1 = new int[(Xmax - Xmin + 1)]; //массив левых границ для первой функции
for (int i = 0; i < (Xmax - Xmin + 1); i++) {
result[i] = 0;
LGr1[i] = Xmin + i;
}
func(arr, Xmin, result, length_);
print_task(result, LGr1, (Xmax - Xmin + 1));
int count_; //количество интервалов разбиения
do {
cout << "Введите количество интервалов разбиения\n";
cin >> count_;
} while ((count_ > 24) || (count_ < 1) || (count_ >(Xmax - Xmin + 1)));
int *LGr2 = new int[count_]; //массив левых границ для второй функции
int i = 0;
cout << "Введите левые границы интервалов разбиения\n"
" 1-я граница - начало отрезка ("<< Xmin <<") \n\n";
LGr2[i] = Xmin;
for (int j = 1; j < count_; j++) {
do {
cout << "Введите " << j + 1 << "-ю границу\n";
cin >> LGr2[j];
} while ((LGr2[j] < Xmin) || (LGr2[j] > Xmax));
}
sort(LGr2, count_);
print(LGr2, count_);
int *result_final = new int[count_]; //массив полученного распределения
for (int i = 0; i < count_; i++) {
result_final[i] = 0;
}
// func2(result, LGr2, result_final, (Xmax - Xmin), Xmin, count_);
func2_1(result, LGr2, result_final, (Xmax - Xmin), Xmin, count_);
print_task(result_final, LGr2, count_);
system("pause");
return 0;
}
lr6.asm
.MODEL FLAT, C
.CODE
PUBLIC C func
func PROC C arr:dword, Xmin:dword, res:dword, length_:dword
push edi
push esi
mov eax,arr
;массив псевдослучайных чисел
mov ebx,res
;массив результирующего распределения
mov edx,00000001h
;счетчик для увеличения количества попаданий
mov esi,00000000h
;счетчик цикла
CYCLE:
mov edi,[eax+4*esi] ;запись i-го элемента из массива псевдослучайных чисел
sub edi,Xmin
;вычисление индекса отрезка в массиве распределения,
соответствующего данному элементу
add [ebx+4*edi], edx ;добавление попадания i-го элемента в отрезок
inc esi
;инкрементирование счетчика
cmp esi,length_
;проверка на конец цикла
jl CYCLE
pop esi
pop edi
ret
func ENDP
END
lr6_2.asm
.MODEL FLAT, C
.DATA
help dword 0
.CODE
PUBLIC C func2_1
func2_1 PROC C arr:dword, LGr:dword, res:dword, length_big:dword, Xmin:dword,
length_:dword
push edi
push esi
mov eax,arr
;исходный массив распределения
mov ebx,res
;конечный массив распределения
mov ecx,LGr
;массив левых границ
mov edx,Xmin
;самая первая левая граница
mov esi,00000000h ;счетчик цикла
mov edi,esi
;счетчик, отвечающий за промежуток, в который нужно записывать
jmp STEP
CYCLE:
add ecx,00000004h ;рассматриваем следующую левую границу
inc edi
STEP:
cmp edi,length_
;если счетчик равен длине массива левых границ (точка попала в
последниий промежуток)
je STEP2
cmp edx,[ecx] ;сравнение текущей точки со следующей левой границей
jge CYCLE
;если больше или равна, то сравниваем следующую точку
STEP2:
dec edi
mov ecx,[eax+4*esi] ;запись количества попаданий псевдослучайн. чисел в текущую точку во
вспомогат. переменную
add [ebx+4*edi],ecx ;добавление количества попаданий в промежуток, соответствующий данной
точке
cmp esi,length_big ;проверка, не достигнут ли конец исходного массива
je END_OF_CYCLE
;если достигнут - выход из программы
inc esi
;инкрементирование счетчика цикла
inc edx
;инкрементирование точки
mov edi,00000000h
;обнуление счетчика, отвечающего за промежуток
mov ecx,LGr
;перезапись начала массива левых границ
jmp STEP
END_OF_CYCLE:
pop esi
pop edi
ret
func2_1 ENDP
END
Download