Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ВМСиС_лаборАА.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
272 Кб
Скачать
☆

Задание

Требуется написать и отладить программу на языке ассемблера, эквивалентную следующему фрагменту программы на языке C.

If((x > y) && (z < t) || (a != b)) c = d.

Для временного хранения переменных a, b, c, d, x, y, z, t используйте регистр AX. Для реализации проверки условий используйте команду CMP, которая осуществляет вычитание источника (второй операнд команды) из приемника (первый операнд команды). Счет операндов осуществляется слева направо. В результате вычитания устанавливаются соответствующие флаги, для проверки которых используется команды условного перехода jne, jng, jnl.

Требуется написать и отладить программу, реализующую структуру управления CASE, на основе использования таблицы переходов. В данном примере используется пустая последовательность операторов для каждой метки выбора. Фрагмент программы CASE представлен ниже.

mov bx,I; значение I от 0 до 2 определяет набор операторов, соответствующих метке выбора

;shl bx,1; умножение на два (если размер адреса в таблице переходов составляет 4 байта)

Jmp cs:jump_table[bx]

jump_table dw foo0, foo1, foo2; таблица переходов

foo0:

call case0

jmp endcase

foo1:

call case1

jmp endcase

foo2:

call case2

jmp endcase

case0:

ret; пустая последовательность операторов

case1:

ret

case2:

ret

endcase:

mov ax,4C00h

int 21h

END begin; метка начала программы

Лабораторная работа 5. Изучение инструкций преобразования операндов.

Цель: освоение процесса отладки программы, вычисляющей заданную функцию.

Работа осуществляется с использованием средств ассемблирования и средств отладки. Необходимые для работы инструментальные программы расположены в файле Lab_asm.exe.

Задание

Требуется разработать на языке Ассемблер IBM PC программу, которая по заданным целым значениям a, b, i, k вычисляет сначала значения i1 = fn1(a, b, i) и i2 = fn2(a, b, i), а затем значение res = fn3(i1, i2, k). Вид функций fn1, fn2  определяется из табл. 1, а вид функции fn3 - из табл. 2. Символы n1, n2, n3, используемые в описании функции f, соответствуют числовым индексам функции, которые представлены тремя соответствующими цифрами в табл. 3 индивидуальных заданий (n1, n2, n3) для бригады.

Значения a, b, i, k являются исходными данными, которые должны выбираться студентом самостоятельно и задаваться в процессе исполнения программы в режиме отладки. При этом следует рассмотреть всевозможные комбинации параметров a, b и k, позволяющие проверить различные маршруты выполнения программы (по указанию преподавателя).

Внимание. Возможно использование следующего упрощенного задания. Требуется разработать на языке Ассемблер IBM PC программу, которая по заданным целым значениям a, b, i вычисляет значения i1 = fn1(a, b, i) и i2 = fn2(a, b, i). Вид функций fn1, fn2  определяется из табл. 1. Символы n1, n2, используемые в описании функции f, соответствуют числовым индексам функции, которые представлены двумя соответствующими цифрами в табл. 3 индивидуальных заданий (n1, n2) для бригады. Значения a, b, i являются исходными данными, которые должны выбираться студентом самостоятельно и задаваться в процессе исполнения программы в режиме отладки. При этом следует рассмотреть всевозможные комбинации параметров a, b, позволяющие проверить различные маршруты выполнения программы (по указанию преподавателя).

Рекомендуется при вычислении функций fn1 и fn2 вместо операции умножения использовать арифметический сдвиг и, возможно, сложение. При реализации функций fn1 и fn2 следует стремиться к минимизации длины кода.

Таблица 1

Таблица 2

при a > b

при a ≤ b

min (i1, i2), при k=0

max (i1, i2), при k≠0

при a > b

при a ≤ b

max (i1, 10-i2), при k<0

‌|i1‌‌-i2|, при k≥0

при a > b

при a ≤ b

|i1‌‌+i2|, при k=0

min (i1, i2), при k≠0

при a > b

при a ≤ b

min (i1, 8), при k<0

max (8, i2), при k≥0

при a > b

при a ≤ b

min (|i1|, 6), при k=0

|i1|+|i2|, при k≠0

при a > b

при a ≤ b

|i1|-|i2|, при k<0

max (7, |i2|), при k≥0

Таблица 3

Номер бригады по списку

Числовые индексы функций, выбираемых из табл.1 и табл. 2

n1

n2

n3

1

1

2

1

2

2

3

2

3

3

4

3

4

4

5

4

5

5

6

5

6

6

1

6

7

1

3

1

8

2

4

2


Лабораторная работа 6. Процедуры.

Цель: освоение средств обеспечивающих модульное программирование.

. Необходимые пояснения.

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

main

М1.1

М1.2

М1.3

М1

М1.4

М1.1.1

М1.1.2

При завершении описания модуля main в директиве end необходимо указать стартовую метку (только в main!). Когда создается многомодульная программа, требуются глобальные и локальные метки и переменные. Переменная – это информационный объект, имеющий текущее значение, имя, обозначающее адрес хранения текущего значения и структуру, которая может быть простой (из одного элемента) или составной. Для обеспечения взаимодействия модулей необходимо объявить глобальные метки и переменные. Объявление меток и переменных производится с помощью двух списков, задаваемых директивами EXTRN и PUBLIC. Список, задаваемый в модуле директивой EXTRN, содержит идентификаторы внешних переменных и меток, к которым осуществляется обращение из данного модуля. Второй список содержит внутренние идентификаторы, к которым разрешено обращаться из других модулей.

Далее приводятся описания некоторых директив.

Директива TITLE.

Директива TITLE текст, представляющий заголовок листинга, инициирует печать на каждой странице листинга заголовка, включающего имя модуля (6 символов) и описание (60 символов) его назначения. Листинг представляет собой текстовый файл, содержащий описание исходной ассемблерной программы, код каждой ассемблированной команды, список используемых меток, описание перекрестных ссылок, сегментов и групп сегментов.

Директивы EXTRN и PUBLIC.

Необходимость использования директив EXTRN и PUBLIC возникает при описании взаимодействующих программных модулей.

Пусть два модуля взаимодействуют следующим образом. В модуле 1 осуществляется изменение данных, хранимых в переменной F, определенной в модуле 2. Для объявления глобальной переменной F используются директивы EXTRN и PUBLIC. Для определения переменной F необходима директива, задающая тип переменной. В качестве такой директивы можно использовать, например, директиву DB – определить байт (define byte). Определение переменной задается строкой, разделенной пробелами на три части. В начале строки размещается идентификатор – имя переменной. Далее размещается аббревиатура директивы, указывающей тип именованной переменной. После аббревиатуры директивы следует перечень значений и специальных операторов, разделенных запятыми. В качестве значений используются четыре типа констант. Целые константы, заданные с помощью цифр требуемой системы счисления. Константы с плавающей запятой. Символьные константы, представленные символом, размещенным между двумя апострофами. Строковые литералы, представляемые последовательностью символов, размещенных между знаками двойных кавычек. В качестве специальных операторов используются оператор повторения константы DUP, который может быть вложенным и оператор ? задания неопределенного значения.

При описании взаимодействующих модулей mod1 и mod2 необходимо в директиве EXTRN для объявляемых переменных и меток указать тип, который соответствует типу, заданному при определении переменных и меток.

TITLE mod1 TITLE mod2

EXTRN F:BYTE; внешняя глобальная переменная. PUBLIC F

DATA SEGMENT; начало сегмента с именем DATA. DATA SEGMENT

DATA ENDS F DB ?; переменная F типа байт

DATA ENDS

CODE SEGMENT CODE SEGMENT

ASSUME CS:CODE, DS:DATA CODE ENDS

START: END

MOV AX, DATA

MOV DS, AX

MOV F, 5

CODE ENDS

END START

Операнды директив EXTRN и PUBLIC разделяются запятыми.

EXTRN имя:ТИП, …, имя:ТИП

PUBLIC имя, …, имя

Типы для переменных: byte, word, dword, а другие можно найти в справочнике.

Типы для меток:

NEAR – указывает на размещение метки внутри сегмента;

FAR – указывает на размещение метки за пределами данного сегмента;

SHORT – метки указанного типа используется в инструкциях перехода для задания адреса назначения. Пределы перехода от текущей команды ограничены величинами +127 и -128 байт.

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

Директива описания процедуры.

Процедура – это поименованная часть программы. Используется для структурирования программы. Вызывается с помощью команды: call имя_процедуры. При работе с процедурами необходимо следить за состоянием используемого стека. Для оформления процедуры используется директива PROC, имеющая следующий формат описания.

имя proc атрибуты

---------------------

операторы процедуры

---------------------

ret; команда завершения процедуры

имя endp

При выполнении команды ret из стека извлекается на регистр IP адрес возврата, который был помещен в стек при выполнении команды call.

Адрес возврата может быть дальний (far). Для его хранения используются 2 слова, которые из стека перемещаются в регистры CS:IP. Если адрес возврата ближний (near), тогда для хранения используется 1 слово, перемещаемое в регистр IP. Размер слова – 2 байта. Для указания типа адреса возврата используется атрибут в директиве proc. Тип атрибута определяется местоположением тела процедуры по отношению к оператору вызова процедуры call

а) Если call и тело процедуры расположены в одном сегменте кода и в одном модуле, то используется near. Указывать явно необязательно.

б) Если call и тело процедуры расположены в разных сегментах, но в одном модуле, то используется тип far и атрибутный оператор ptr (указатель).

call FAR PTR имя

в) Если call и тело процедуры расположены в разных сегментах и в разных модулях, то используется far и еще требуется в начале модуля основной программы, содержащей call, указать имя процедуры в списке extrn, а в модуле, содержащем тело процедуры, указывается имя процедуры в списке public. В операторе call использовать тип и атрибутный оператор FAR PTR не требуется.

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

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