90919

Интерфейс Ассемблера с языками высокого уровня. Обработка массивов данных

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

Информатика, кибернетика и программирование

При работе с символьными строками в языке Ассемблера необходимо придерживаться тех же принципов что и в языке Си: строка – это массив символов имя строки – это адресный указатель на её самый первый элемент размер каждого символа равен одному байту каждый символ определен кодом в таблице SCII любая информативная строка должна заканчиваться символом конца строки символом с кодом 0. Задания к лабораторной работе исходные данные Ассемблерная функция имеет прототип вида...

Русский

2015-07-10

96 KB

0 чел.

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

Интерфейс Ассемблера с языками высокого уровня. Обработка массивов данных

2.1. Цель работы

Ознакомиться с режимами адресации, организацией циклов, правилами оформления ассемблерных процедур и командами передачи управления. Изучить общие принципы интерфейса Ассемблера с языками высокого уровня на примере взаимодействия ассемблерной процедуры и функции, написанной на языке Си.

2.2. Краткие теоретические сведения

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

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

mov ax, bx;

Непосредственная адресация. Значение операнда является частью машинной команды и представляет собой константу:

add bx,1234h;

Неявная адресация. Местоположение операнда фиксировано и определяется кодом операции. Например, у команды MUL фиксировано положение первого множителя и результата:

mul al;

Абсолютная прямая адресация. В машинной команде содержится адрес операнда, находящегося в памяти. В примере в регистр DX помещается значение из памяти по адресу a, квадратные скобки обозначают обращение по адресу, указанному внутри этих скобок:

mov dx,[a];

Относительная прямая адресация. Этот режим используется в командах передачи управления. В машинной команде содержится смещение, которое прибавляется к значению указателя команд IP. То есть указывается не сам адрес перехода, а на сколько байтов вперёд или назад надо перейти:

metka:

...

     loop metka;

Косвенная регистровая (базовая) адресация. Адрес операнда находится в одном из регистров BX, SI или DI:

add ax,[bx]

mov dl,[si];

Косвенная регистровая (базовая) адресация со смещением. Адрес операнда вычисляется как сумма содержимого регистра BX, BP, SI или DI и 8- или 16-разрядного смещения:

add ax,[bx+2]

mov dx,[array1+si];

Косвенная базовая индексная адресация. Адрес операнда вычисляется как сумма содержимого одного из базовых регистров BX или BP и одного из индексных регистров SI или DI:

mov ax,[bp+si]

add ax,[bx+di];

Косвенная базовая индексная адресация со смещением. Адрес операнда вычисляется как сумма содержимого одного из базовых регистров BX или BP, одного из индексных регистров SI или DI и 8- или 16-разрядного смещения:

mov al,[bp+di+5]

mov bl,[array2+bx+si].

Оформление процедур. Ассемблер имеет средства упрощенного  программирования процедур, предназначенных для вызова из СИ-программ. Они позволяют выполнить соглашения о характеристиках  сегментов,  модели памяти, правилах передачи параметров и использовании регистров.

Оформленная таким образом ассемблерная процедура имеет вид

.MODEL SMALL,С

func PROC NEAR USES SI DI, a:WORD, b:WORD

LOCAL X:WORD, y:WORD

RET

func ENDP

Процедуре func соответствует следующий прототип в СИ-программе:

int func(int a, int b);

При входе в ассемблерную процедуру в стеке будут сохранены регистры SI и DI и размещены локальные переменные х и у. Доступ к этим данным организуется с помощью адресации по базе с использованием регистра ВР. При этом нет необходимости вычислять смещения вручную, поскольку ассемблер автоматически генерирует макроподстановки типа a EQU <WORD PTR [bp+6]>. В тексте программы в качестве операндов можно использовать имена локальных переменных и  передаваемых  параметров.

По команде RET автоматически генерируются команды восстановления регистров SI,  DI,  ВР,  SP и только затем выполняется возврат в вызывающую программу. В ассемблерной  процедуре  можно свободно использовать регистры AX, BX, CX, DX. Остальные регистры должны быть сохранены и затем восстановлены.

2.3. Методические указания

При написании программных модулей особое внимание обратите на соглашения интерфейса Си-Ассемблер. Необходимо, чтобы в именах функций, процедур и параметров, используемых одновременно в модулях на Си и на Ассемблере, учитывался регистр букв, т.е. соблюдались правила более строгого синтаксиса языка Си.

При работе с символьными строками в языке Ассемблера необходимо придерживаться тех же принципов, что и в языке Си: строка – это массив символов, имя строки – это адресный указатель на её самый первый элемент, размер каждого символа равен одному байту, каждый символ определен кодом в таблице ASCII, любая информативная строка должна заканчиваться символом конца строки (символом с кодом 0).

Также, следует обращать внимание на правила использования того или иного вида адресации. Например, следует помнить, что в одной команде нельзя одновременно использовать два операнда из памяти, а также то, что косвенное обращение через адреса операндов возможно только с использованием регистров BX, BP, SI, DI. Кроме этого, при использовании в процессе выполнения программы стека регистр BP для хранения произвольных адресов лучше не задействовать.

При организации цикла внимательно проверяйте корректность условия выхода из него. При использовании команд LOOP|LOOPE|LOOPNE не забывайте про неявное использование ими регистра CX в качестве счетчика числа итераций. Отследить возникшее в программе бесконечное зацикливание возможно при помощи её пошаговой отладки.

Для возможности вызова ассемблерной процедуры из СИ-функции отдельно написанные программные модули «*.с» и «*.asm» необходимо объединить в совместный проект. В редакторе QC роль проекта выполняет так называемый MAK-файл, т.е. файл с расширением «mak». В нём вручную должны быть прописаны имена программных модулей, входящих в состав единого проекта. Создать MAK-файл можно с помощью последовательности команд главного меню QC: Make – Set Program List – Add. При этом необходимо, чтобы программные модули, объединенные в один проект, имели разные имена до расширения, например, lab2-1.c и lab2-2.asm. В противном случае файлы объектных кодов, создаваемые компилятором последовательно для каждого программного модуля проекта и имеющие в качестве имени имя файла с исходным текстом программы + расширение «obj», перезапишут друг друга. Например, для программных модулей lab2.c и lab2.asm компилятором QC будут созданы последовательно в одной директории файлы lab2.obj и lab2.obj. В итоге, второй OBJ-файл просто перезапишет первый.

В настройках QC обязательно проверьте и при необходимости установите режимы работы компилятора: OptionsMakeCompiler flagsMemory modelSmall, а также компоновщика: OptionsMakeLinker flagsStack Size – 4096.

2.4. Порядок выполнения работы

1. Напишите программный модуль на языке Си, осуществляющий ввод исходных данных, вызов ассемблерной процедуры обработки и вывод результатов обработки. Модуль на Си должен содержать:

  •  прототип ассемблерной процедуры;
  •  ввод исходных данных с подсказками;
  •  вызов ассемблерной процедуры;
  •  вывод результатов работы ассемблерной процедуры.

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

3. Объедините модули с программами на Си и Ассемблере в один проект, выполните компиляцию и произведите отладку на не менее трёх тестовых примерах.

2.5. Задания к лабораторной работе, исходные данные

Ассемблерная функция имеет прототип вида int func(char *strl, char *str2, int n);

Здесь strl и str2 – две символьных строки длиной не менее 10 элементов каждая,  содержащие алфавитно-цифровые символы. Параметр n является одновременно и передающим в ассемблерную процедуру из Си-функции некоторое целое значение, и возвращающим из процедуры в функцию результат вычислений в соответствии с заданием варианта.

Таблица 2.1.

Вар. №

Задание

1

1. Определить длины строк;

2. В конец первой строки дописать вторую строку;

3. В результирующей строке пять символов, начиная с символа n, заменить на пробелы;

4. Вернуть в вызывающую программу сумму длин строк.

2

1. Определить длины строк;

2. Переставить элементы первой строки в обратном порядке;

3. Во второй строке первые n символов заменить на пробелы;

4. Вернуть в вызывающую программу разность длин строк.

3

1. Определить длины строк;

2. В конец первой строки дописать первые n символов из второй строки;

3. Поменять местами второй и четвертый байты второй строки;

4. Вернуть в вызывающую программу длину второй строки.

4

1. Определить длины строк;

2. Поменять местами соответствующие элементы первой и второй строк, до n-го элемента включительно;

3. Поменять местами второй и третий элементы второй строки;

4. Вернуть в вызывающую программу длину первой строки.

5

1. Определить длины строк;

2. Первые n символов первой строки заменить на пробелы;

3. Во второй строке поменять местами первую и четвертую пары символов;

4. Вернуть в вызывающую программу разность длин строк.

6

1. Определить длины строк;

2. Каждый  n-й  элемент  первой  строки заменить на первый элемент второй строки;

3. Во второй строке поменять местами первый и последний элементы;

4. Вернуть в вызывающую программу первый элемент второй строки.

7

1. Определить длины строк;

2. В конец второй строки дописать первую строку;

3. В результирующей строке поменять местами первые n символов с последними n символами по принципу: первый символ с последним, второй с предпоследним и т.д.;

4. Вернуть в вызывающую программу сумму длины первой строки и числа n.

8

1. Определить длины строк;

2. В первой строке сдвинуть все элементы на одну позицию вправо, а последний элемент должен перейти на первую позицию;

3. Во второй строке первые n элементов заменить на буквы латинского алфавита по принципу: первый элемент на «a», второй элемент на «b» и т.д.;

4. Вернуть в вызывающую программу сумму длины второй строки и числа n.

9

1. Определить длины строк;

2. Во второй строке заменить первые 5 элементов на цифры, соответствующие порядковому номеру элемента, т.е. первый элемент на символ «1», второй элемент на символ «2» и т.д.;

3. В первой строке последние n элементов заменить на пробелы;

4. Вернуть в вызывающую программу разность длины первой строки и числа n.

10

1. Определить длины строк;

2. В конце первой строке дописать вторую строку в обратном порядке следования её элементов;

3. В результирующей строке четные элементы заменить на символ «*», а нечетные на символ «+». Количество замен равно числу n;

4. Вернуть в вызывающую программу разность длины первой строки и числа n.

11

1. Определить длины строк;

2. В первой строке каждый буквенный символ нижнего регистра заменить на соответствующий символ верхнего регистра;

3. Во второй строке первые n символов заменить на последний символ строки;

4. Вернуть в вызывающую программу произведение длин строк.

12

1. Определить длины строк;

2. В конец первой строки дописать эту же строку, переписанную в обратном порядке следования символов;

3. Во второй строке n элементов, начиная с 4-го, заменить на символ «-»;

4. Вернуть в вызывающую программу итоговую длину первой строки.

13

1. Определить длины строк;

2. Каждый  n-й  элемент  первой  строки заменить на последний элемент второй строки;

3. Во второй строке сохранить только первые 5 элементов и затем переписать их в обратном порядке следования;

4. Вернуть в вызывающую программу n-й элемент первой строки.

14

1. Определить длины строк;

2. Поменять местами соответствующие последние n элементов в первой и второй строках;

3. В первой строке ASCII-код каждого 3-го элемента увеличить на 3;

4. Вернуть в вызывающую программу удвоенную длину первой строки.

15

1. Определить длины строк;

2. В конец второй строки дописать последние n символов из первой строки;

3. В первой строке поменять местами второй и предпоследний элементы;

4. Вернуть в вызывающую программу длину второй строки.

16

1. Определить длины строк;

2. В конец первой строки дописать 5 раз последний элемент второй строки;

3. Во второй строке нечетные элементы заменить на символ с ASCII кодом n;

4. Вернуть в вызывающую программу длину первой строки.

17

1. Определить длины строк;

2. Переставить элементы обеих строки в обратном порядке;

3. К n первым элементам первой строки дописать n первых элементов второй строки;

4. Вернуть в вызывающую программу длину второй строки.

18

1. Определить длины строк;

2. В первой строке первые n пар символов заменить на пару символов «12»;

3. Во второй строке поменять местами первый и второй символы, а также последний и предпоследний;

4. Вернуть в вызывающую программу сумму длин строк.

19

1. Определить длины строк;

2. Во второй строке последние n элементов заменить на цифры 1, 2…n;

3. Первую строку сделать зеркальной относительно своей левой половины;

4. Вернуть в вызывающую программу разность первой строки и числа n.

20

1. Определить длины строк;

2. Каждый n символ первой строки заменить на пробел;

3. Во второй строке ASCII-код каждого четного элемента увеличить на 1, а каждого нечетного уменьшить на 1;

4. Вернуть в вызывающую программу разность длин строк.

21

1. Определить длины строк;

2. Первые n элементов первой строки заменить на первые n элементов второй строки;

3. Во второй строке поменять местами третий и предпоследний элементы;

4. Вернуть в вызывающую программу второй элемент первой строки.

22

1. Определить длины строк;

2. В конец второй строки дописать последние n элементов первой строки;

3. В результирующей строке заменить на пробелы первые 3 элемента;

4. Вернуть в вызывающую программу сумму длин строк.

23

1. Определить длины строк;

2. Во второй строке каждый буквенный символ верхнего регистра заменить на соответствующий символ нижнего регистра;

3. В первой строке последние n символов заменить на первый символ строки;

4. Вернуть в вызывающую программу удвоенную сумму длин строк.

24

1. Определить длины строк;

2. В первой строке оставить первые n элементов и дописать к ним в конце последние n элементов второй строки;

3. Во второй строке оставить только символы букв нижнего регистра, удалив все остальные элементы;

4. Вернуть в вызывающую программу длину первой строки, умноженную на n.

25

1. Определить длины строк;

2. Во второй строке первые n элементов  заменить на предпоследний элемент первой строки;

3. В первой строке сохранить только последние n элементов, а первым элементов в новой строке сделать символ «*»;

4. Вернуть в вызывающую программу n-й элемент второй строки.

26

1. Определить длины строк;

2. Поменять местами обе строки;

3. В первой строке каждый n-й элемент заменить на первый элемент второй строки;

4. Вернуть в вызывающую программу удвоенную длину первой строки.

27

1. Определить длины строк;

2. В конце второй строки дописать еще раз вторую строку;

3. В первых n элементах первой строки заменить каждый четный элемент на символ «@»;

4. Вернуть в вызывающую программу произведение длин строк.

28

1. Определить длины строк;

2. В конец второй строки дописать n раз первый элемент первой строки;

3. В первой строке все нечетные элементы заменить на символ «?»;

4. Вернуть в вызывающую программу длину первой строки.

29

1. Определить длины строк;

2. В первой строке оставить первые n элементов и дописать к ним в конце зеркальное отражение этих же элементов;

3. Во второй строке удалить все символы цифр;

4. Вернуть в вызывающую программу длину второй строки.

30

1. Определить длины строк;

2. В конце второй строки дописать n раз пару первого и последнего символов второй строки;

3. В первой строке удалить первые 2 и последние 3 элемента;

4. Вернуть в вызывающую программу сумму длин строк.

  1.  Содержание отчёта

  1.  Титульный лист;
  2.  Цель работы;
  3.  Задание в соответствии с вариантом;
  4.  Исходные данные и полученные результаты;
  5.  Листинг конечного варианта программы с необходимыми пояснениями и комментариями;
  6.  Содержательный вывод.

  1.  Примеры контрольных вопросов

  1.  Сравните прямой и базовый методы адресации.
  2.  Что собой представляет регистровый и непосредственный методы адресации?
  3.  Назовите известные вам команды условной и безусловной передачи управления, поясните принцип их работы.
  4.  Назовите известные вам команды вызова подпрограммы и возврата.
  5.  Расскажите о правилах оформления ассемблерных процедур.
  6.  Поясните принципы интерфейса «Си-Ассемблер».
  7.  Расскажите про принципы организации циклов в программе на языке Ассемблера, приведите пример.
  8.  Расскажите, как в программе на языке Ассемблера объявляются массивы и как происходит обращение к их элементам в программе, что представляет собой строка символов?
  9.  Расскажите про назначение регистров SI и DI и команды, работающие с ними неявно.
  10.  Что собой представляет ассемблерная вставка в программе на языке Си?


 

А также другие работы, которые могут Вас заинтересовать

62335. Политическое поведение 17.55 KB
  В политологии под термином политическое поведение понимают: Действия отдельных субъектов политики и массовые политические действия Активность организованных субъектов власти и стихийные действия толпы Акции в поддержку действующей политической системы и действия...