Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции / GL13.doc
Скачиваний:
21
Добавлен:
20.05.2014
Размер:
209.92 Кб
Скачать

Задание a5 Пример программы, включающей битовые операции Формулировка задания

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

В Turbo Debugger записать в файл протокола окна данных до и после выполнения программы. Записать туда же состояние стека в момент выполнения подпрограммы обработки элемента и интерпретировать его.

Отчет должен содержать:

1) распечатки файлов с программами и макросом,

2) распечатка окон с данными до и после выполнения программы,

3) окно стека с комментариями,

4) адрес подпрограммы обработки массива:

из листингов программ,

из карты памяти,

из отладчика.

5) размер кода и данных программы.

Задание. Дан массив слов (байтов) указанного размера. Над каждым элементом массива выполнить операцию: если битовое поле 6:4 совпадает с битовым полем 2:0 и с заданным образцом, то установить старший бит элемента, иначе — сбросить его.

Тексты программ

При выполнении задания вам придется как бы раздвоиться: на разработчика программы и ее пользователя. Разработчик пишет подпрограмму обработки массива и макрос, который дает возможность ее удобного использования. Пользователь пишет главную программу и испытывает подпрограмму на различных входных данных.

По условию задачи следует разместить программу и подпрограммы в разных файлах. Сначала напишем подпрограммы. Разместим их в файле sub6v0.asm. Сконструируем шаблон (рис.6.1) для слова и байта одновременно (можно, конечно, использовать и несколько шаблонов).

15

14

13

12

11

10

 9

 8

 7

 6

 5

 4

 3

 2

 1

 0

b15

d2

b7

f6_4

d1

f2_0

Рис.6.1.

Фактически для нас представляют интерес только интерес только поля f6_4 и f2_0, из которых берутся исходные данные, и поля b15 и b7, которые (возможно) претерпевают изменения. Но приходится вводить названия и для неиспользуемых полей d1 и d2, в соответствии с синтаксисом описания RECORD.

sub5v0.asm

JUMPS ; Оптимизация переходов

.286 ; Разрешены инструкции 286-го процессора

TypeByte EQU 1

TypeWord EQU 2

PUBLIC treat_array

.MODEL small

.CODE

;--------------------------------------------------------------------

; Подпрограмма обработки элемента массива

; Вход: AX(AL) — элемент массива

; BP — образец

; DX — тип элементов (1 - байты, 2 - слова)

; Выход: AX(AL) - измененный элемент массива

;--------------------------------------------------------------------

treat_elem PROC

template RECORD b15:1, d2:7, b7:1, f6_4:3, \

d1:1, f2_0:3

push ax bx ; Сохранить рабочие регистры

mov bx,ax ; Дублировать элемент в bx

and ax,MASK f6_4 ; Выделить битовое поле 6:4

shr ax,f6_4 ; Прижать его к правому краю

and bx,MASK f2_0 ; Выделить битовое поле 2:0

cmp ax,bx ; Сравнить битовые поля

jne clear ; Если не совпадают, сбросить старший бит

cmp ax,bp ; Сравнить битовое поле с образцом

jne clear ; Если не совпадают, сбросить старший бит

; Установка старшего бита

pop bx ax ; Восстановить регистры

cmp dx,TypeWord ; Если тип операнда слово –

je set_b15 ; на set_b15

or al, MASK b7 ; Иначе — установить старший бит байта

jmp ret_elem ; На выход

set_b15:

or ax, MASK b15 ; Установить старший бит слова

jmp ret_elem

; Сброс старшего бита

clear: pop bx ax

cmp dx, TypeWord

je clear_b15

and al, NOT MASK b7 ; Сбросить старший бит байта

jmp ret_elem

clear_b15:

and ax, NOT MASK b15 ; Сбросить старший бит слова

ret_elem:

ret

treat_elem ENDP

;-------------------------------------------------------------------

; Подпрограмма обработки массива

; Вход: SI — адрес массива

; CX — количество элементов

; BP — образец

; DX — тип элементов (1 - байты, 2 - слова)

; Выход: CF = 1, если входной массив пуст

; CF = 0, если входной массив непуст

; Результат: измененный массив

;-------------------------------------------------------------------

treat_array PROC

jcxz error ; Если массив нулевой длины — на error

m: mov ax,[si] ; Загрузить очередной элемент в AX (в AL)

call treat_elem ; Обработать элемент

mov [si],ax ; Вернуть элемент в массив

add si,dx ; Переместить указатель на следующий элемент

loop m

clc ; Нормальное завершение

ret

error: stc; Сообщение об ошибке, если массив пустой

ret

treat_array ENDP

END

Обратим внимание на следующие моменты.

1) Мы сообщаем компилятору директивой

PUBLIC treat_array

что treat_array — это глобальное имя, т.е. оно будет использоваться программами, расположенными в других файлах. Спецификатор PROCозначает, что это имя некоторой процедуры. Компилятор разместит это имя в таблице глобальных имен. Ей впоследствии воспользуется компоновщик.

2) Директива ENDне содержит метки стартового адреса, т.к. в файле нет главной программы — только подпрограммы.

3) Вместо того чтобы записывать команды

push ax

push bx

мы записываем эти команды одной строкой. Такую возможность предоставляет Turbo Assembler.

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

Файл с макросом для вызова подпрограммы treat_array.

macr5v0.inc

TypeByte EQU 1

TypeWord EQU 2

;---------------------------------------------------------------------

; Макрос вызова подпрограммы обработки массива

; array — имя массива

; len_of_array — количество элементов массива

; pattern — образец

; error_label — метка для перехода по ошибке

;---------------------------------------------------------------------

treat MACRO array, len_of_array, pattern, error_label

TA = TYPE array

Соседние файлы в папке Лекции