Задания для самостоятельной работы




Лабораторная работа №4

Процедуры в ассемблере

Теоретическая часть

До сих пор мы рассматривали примеры программ, предназначенные для однократного выполнения. Но, приступив к программированию достаточно серьезной задачи, вы наверняка столкнетесь с тем, что у вас появятся повторяющиеся фрагменты кода. Одни из них могут состоять всего из нескольких команд, другие занимать и достаточно много места в исходном коде. В последнем случае эти фрагменты существенно затруднят чтение текста программы, снизят ее наглядность, усложнят отладку и послужат неисчерпаемым источником ошибок. В языке ассемблера есть несколько средств, решающих проблему дублирования фрагментов программного кода. К ним относятся:

  • процедуры;
  • макроподстановки (макроассемблер);
  • генерация и обработка программных прерываний.

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

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

  • в начале программы (до первой исполняемой команды);
  • в конце программы (после команды, возвращающей управление операционной системе);
  • промежуточный вариант — внутри другой процедуры или основной программы (в этом случае необходимо предусмотреть обход процедуры с помощью команды безусловного перехода JМР);
  • в другом модуле (библиотеке DLL).

Размещение процедуры в начале сегмента кода предполагает, что последовательность команд, ограниченная парой директив PROC и ENDP, будет размещена до метки, обозначающей первую команду, с которой начинается выполнение программы. Эта метка должна быть указана как параметр директивы END, обозначающей конец программы.

Объявление имени процедуры в программе равнозначно объявлению метки, поэтому директиву PROC в частном случае можно рассматривать как завуалированную форму определения программной метки. Поэтому сама исполняемая программа также может быть оформлена в виде процедуры, что довольно часто и делается с целью пометить первую команду программы, с которой должно начаться выполнение. При этом не забывайте, что имя этой процедуры нужно обязательно указывать в заключительной директиве END.

Размещение процедуры в конце программы предполагает, что последовательность команд, ограниченная директивами PROC и ENDP, находится следом за командой, возвращающей управление операционной системе.

Промежуточный вариант расположения тела процедуры предполагает ее размещение внутри другой процедуры или основной программы. В этом случае необходимо предусмотреть обход тела процедуры, ограниченного директивами PROC и ENDP, с помощью команды безусловного перехода JМР.

Последний вариант расположения описаний процедур — в отдельном сегменте кода — предполагает, что часто используемые процедуры выносятся в отдельный файл, который должен быть оформлен как обычный исходный файл и подвергнут трансляции для получения объектного кода. Впоследствии этот объектный файл с помощью утилиты tlink можно объединить с файлом, в котором данные процедуры используются. Этот способ предполагает наличие в исходном тексте программы еще некоторых элементов, связанных с особенностями реализации концепции модульного программирования в языке ассемблера.

Рассмотрим работу с процедурами в ассемблере на примерах из практической части.

Практическая часть

Пример №1. Написать процедуру для суммирования следующим образом:

.

Решение.

Т.е. если преобразовать формулу из условия, то получим формулу для суммирования:

В сегменте данных задана переменная N=3. Далее рассмотрим строку .

- директива;

- имя процедуры;

(stdcall – тип вызова;)

- директива;

- используемые регистры при вызове процедуры, сохраняются, при выходе восстанавливаются. Если необходимо несколько регистров, то они записываются через пробел.

- аргументы процедуры.

Команда RET необходима для выхода в точку вызова.

Далее следует сама процедура и заканчивается командой ENDP.

Так как мы используем соглашение stdcall, то для того чтобы вызвать процедуру необходима запись , где ecx, edx – значения аргументов процедуры, sum – имя процедуры, stdcall – команда вызова процедуры в соответствии с соглашением stdcall (макрос, который разворачивается в команды).

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

Замечание. Заметим, что нам не потребовалось следить за регистрами edx, ecx, так как за этим следит соглашение stdcall.

Пример 2. Определить сколько чисел являющихся палиндромами находятся в диапазоне от 100 до 300. (Определить процедуру нахождения палиндрома)

Решение.

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

Задания для самостоятельной работы

  1. Ознакомьтесь с теоретическим материалом.
  2. Разберите все примеры из практической части лабораторной работы, т.е. наберите и просмотрите их работу.
  3. Выполните индивидуальные задания.

Индивидуальные варианты

№1.

1.1. Найти значение выражения . (Определить процедуру для вычисления факториала.)

1.2. Даны 3 натуральных числа. Выяснить, в каком из них больше цифр. (Определить процедуру для расчета количества цифр натурального числа.)

1.3. Даны 3 натуральных числа. Определить количество чисел являющихся степенями двойки. (Определить процедуру позволяющую распознать степени двойки.)

1.4. Даны 3 натуральных числа. Определить количество чисел являющихся полными квадратами. (Определить процедуру позволяющую распознать полные квадраты.)

1.5. Даны 3 натуральных числа. Выяснить, в каком из них сумма цифр больше. (Определить процедуру для расчета сумма цифр натурального числа.)

№2.

2.1. Найти наибольший общий делитель трех натуральных чисел, имея в виду, что НОД(a,b,c)=НОД(НОД(a,b),c). (Определить процедуру для расчета наибольшего общего делителя двух натуральных чисел, используя алгоритм Евклида).

2.2.Даны n натуральных чисел. Найти НОД, используя алгоритм Евклида. (Определить процедуру для расчета наибольшего общего делителя двух натуральных чисел, используя алгоритм Евклида).

2.3. Даны 2 натуральных числа a и b, обозначающих числитель и знаменатель дроби. Сократить дробь, т.е. найти такие натуральные числа p и q, не имеющих общих делителей, что p/q=a/b Найти их наименьшее общее кратное. (Определить процедуру для расчета наибольшего общего делителя двух натуральных чисел, используя алгоритм Евклида).

2.4. Определить количество «близнецов» двузначных чисел. («Близнецами» называются простые числа отличающиеся друг от друга на 2, например, 41 и 43).Вывести сумму простых трехзначных чисел. (Определить функцию, позволяющую распознавать простые числа.)

2.5. Вывести сумму простых трехзначных чисел. (Определить функцию, позволяющую распознавать простые числа.)



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-04-27 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: