Добавил:
БГУИР ПОИТ Дистанционное Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Часть 1 / ИПР2_В5 / Отчет ИПР2

.docx
Скачиваний:
6
Добавлен:
06.10.2021
Размер:
34.73 Кб
Скачать

БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ

Кафедра программного обеспечения информационных технологий

Факультет ФКСиС

Специальность ПОИТ

Индивидуальная практическая работа № 2

по дисциплине «Языки программирования часть 1»

Вариант 5

Выполнил студент: Бордон Е.С.

группа 991051

Зачетная книжка № 99105004

Минск 2021

Условия задачи

Написать и отладить программу на языке Ассемблер.

Задан одномерный массив. Вывести на экран элементы массива,

кратные 5 и их количество. Массив задать в сегменте данных или ввести с

клавиатуры.

Пояснения к работе программы

Программы написаны на Assembler для MASM для выполнения на современных 32-битных процессорах в ОС Windows с использованием среды разработки SASM и отладчика OllyDbg.

Программа содержит предопределённый в сегменте данных массив четырёхбайтных чисел. При необходимости можно перекомпилировать программу с другим массивом данных.

Результат работы программы

Рис 1. Результат работы программы

Тестовый набор данных:

Массив данных

Числа кратные 5

Число кратных чисел

2,5,11,8,15

5,15

2

1,3,5,7,9,11,15,20

5,15,20

3

500,501,499,6005

500,6005

2

5,5,5,5,5,5,5,5

5,5,5,5,5,5,5,5

8

7,7,7,7,7,7,7,7

7,7,7,7,7,7,7,7

0

Листинг программы

.386 ; код скомпилируется для сравнительно современных 32-битных процессоров

.model flat, stdcall ; устанавливаем модель памяти windows, очистку стека осуществляет вызываемая подпрограмма

option casemap : none ; делаем переменные регистрозависимыми

include \masm32\include\kernel32.inc ; для использования базового API Windows

include \masm32\include\msvcrt.inc ; для использования crt_printf и crt_scanf (ввод/вывод с поддержкой формата)

includelib \masm32\lib\kernel32.lib ; для использования базового API Windows

includelib \masm32\lib\msvcrt.lib ; для использования crt_printf и crt_scanf (ввод/вывод с поддержкой формата)

CRLF equ 13, 10 ; синоним перевода строки в консоли

ELSIZE equ 4

.data

R dd n-1 ; длина прохода - количество неотсортированных элементов минус один

;*****************

array dd 2,5,11,8,15 ; задаём массив 4-байтных чисел

;*****************

n = ($ - array) / ELSIZE ; вычисляем длину массива, как текущая метки минус метка начала массива, разделенная на длину элемента - 4 байта

formatInt db '%d',0 ; описание формата целого числа

formatStr db '%s',0 ; описание формата строки

msgInitial db "Source array is:", CRLF, 0 ; вступление к выводу исходного массива

msgSorted db "Multiple of 5:", CRLF, 0 ; вступление к выводу чисел кратных 5

msgCount db "Total multiples of 5: ", CRLF, 0 ; вступление к выводу чисел кратных 5

msgFinal db "Enter any char and press 'Enter' for exit", CRLF, 0; инструкция по выходу из программы

msgCRLF db CRLF ; перенос строки

.code

start:

invoke crt_printf, ADDR formatStr, ADDR msgInitial ; выводим сообщение о выводе исходного массива

call printArr ; выводим исходный массив и инициализируем esi адресом начала массива

invoke crt_printf, ADDR formatStr, ADDR msgSorted ; выводим сообщение о выводе исходного массива

call printArrr ; выводим результат сортировки

invoke crt_printf, ADDR formatStr, ADDR msgCount ; выводим сообщение о числе кратных чисел

invoke crt_printf, ADDR formatInt, edi ; выводим результат

invoke crt_printf, ADDR formatStr, ADDR msgCRLF ; выводим перенос строки;

invoke crt_printf, ADDR formatStr, ADDR msgFinal ; объясняем, как выйти из программы

invoke crt_scanf, ADDR formatStr, ADDR formatStr ; переиспользуем переменную для хранения ненужных данных

invoke ExitProcess, 0 ; закрываем программу, возвращаемся к ОС

;_____________________________________________________________________________________

printArr proc ; вспомогательная процедура для вывода текущего состояния массива

mov ecx, n ; сохраняем количество элементов для счётчика цикла

mov esi, offset array ; сохраняем адрес начала массива в esi

xor edx, edx ; обнуляем счётчик элементов массива

lp1:

mov ebx, [esi + edx * ELSIZE] ; выбираем текущий элемент массива

push ecx ; сохраняем значение ecx в стек

push edx ; сохраняем значение edx в стек

invoke crt_printf, ADDR formatInt, ebx ; выводим результат

invoke crt_printf, ADDR formatStr, ADDR msgCRLF ; выводим перенос строки

pop edx ; восстанавливаем значение edx из стека

inc edx ; увеличиваем номер для корректного выбора следующего элемента

pop ecx ; восстанавливаем значение ecx из стека

loop lp1 ; привязываем цикл к метке lp1

ret ; возвращаемся в вызвавшую программу

printArr endp ; конец вспомогательной процедуры

;______________________________________________________________________________

;вывод только кратных 5 чисел

;_____________________________________________________________________________________

printArrr proc ; вспомогательная процедура для вывода текущего состояния массива

mov ecx, n ; сохраняем количество элементов для счётчика цикла

mov esi, offset array ; сохраняем адрес начала массива в esi

xor edx, edx ; обнуляем счётчик элементов массива

xor edi, edi ; счетчик числа кратных чисел

;(dx,ax)/bx = ax, dx **** a/b ****

lp1:

mov ebx, [esi + edx * ELSIZE] ; выбираем текущий элемент массива

push ecx ; сохраняем значение ecx в стек

push edx ; сохраняем значение edx в стек

xor edx, edx ; очищаем остаток от деления

mov eax, ebx ; помещаем наше числа в eax

mov ecx, ebx ; ecx наше число

mov ebx, 5 ; наш делитель

div ebx ;(dx,ax)/bx = ax, dx

cmp edx, 0 ; делаем проверку остатка от деления

jl incorrect ; <

jg incorrect ; >

jz correct ; =

correct: ; если число кратно 5

inc edi

mov ebx, ecx

invoke crt_printf, ADDR formatInt, ebx ; выводим результат

invoke crt_printf, ADDR formatStr, ADDR msgCRLF ; выводим перенос строки

JMP exit

incorrect: ; если число не кратно 5

mov ebx, ecx

JMP exit

exit:

pop edx ; восстанавливаем значение edx из стека

inc edx ; увеличиваем номер для корректного выбора следующего элемента

pop ecx ; восстанавливаем значение ecx из стека

loop lp1 ; привязываем цикл к метке lp1

ret ; возвращаемся в вызвавшую программу

printArrr endp ; конец вспомогательной процедуры

;______________________________________________________________________________

end start ; программа начнёт выполнение с метки start

Соседние файлы в папке ИПР2_В5