Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ИУИКСИС Лаб. раб. / 3 / laba_ass_03

.doc
Скачиваний:
9
Добавлен:
15.03.2015
Размер:
73.22 Кб
Скачать

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

Использование макросов в ассемблерных программах

Использование макросов позволяет упростить процесс программирования и существенно улучшить «читабельность» программ.

Целью лабораторной работы является изучение некоторых полезных макросов из файла macros.inc, способов их использования и приобретение навыков в написании и отладке ассемблерных программ.

Конкретные задания на работу выделены в тексте курсивом.

  1. Макроопределения

Макроопределение (макрос) имеет следующую структуру:

<Имя макроса> MACRO [<Формальные параметры через запятую>]

[LOCAL <Перечень локальных меток>]

<Тело макроса>

ENDM,

в […] – скобках указаны необязательные параметры.

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

Ниже приведены примеры некоторых полезных макросов из MACROS.INC.

    1. Ввод символа с клавиатуры

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

GetChar macro

mov ah,01h ; функция DOS 01h – ввод символа

int 21h

endm

Как видно из его описания, макрос не имеет формальных параметров и локальных меток. Эти параметры не являются обязательными. Тело макроса образуют две команды. Первая mov ah,01h задает номер функции DOS в регистре ah (функция 01h - ввод символа с клавиатуры), а вторая int 21h вызывает подпрограмму выполняющую эту функцию. Подпрограмма построена так, что она ожидает ввода и, как только будет нажата любая клавиша, соответствующий ей код символа будет размещен в регистре al.

    1. Сохранение и восстановление регистров

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

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

SaveReg macro RegList

irp reg,<RegList>

push reg

endm

endm

При использовании этого макроса в программе список регистров должен быть заключен в угловые скобки, например - SaveReg <ax,bx,cx>. На первый взгляд может показаться, что директива endm ошибочно написана дважды. Но это не так. Первый раз endm «закнчивает» макрос irp reg,<RegList>, авторой раз – основной макрос SaveReg.

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

LoadReg macro RegList

irp reg,<RegList>

pop reg

endm

endm

При использовании этого макроса в программе список регистров должен быть заключен в угловые скобки, например - LoadReg <cx,bx,ax>, причем обратите внимание на то, что имена регистров должны следовать в порядке обратном тому, в каком они сохранялись.

    1. Переход на следующую строку

Для перевода курсора на экране дисплея на следующую строку надо выполнить два действия: вывести код символа возврата каретки и перевода строки. Макрос NextLine выполняет эти действия с использованием соответствующей функции DOS.

NextLine macro

SaveReg <ax,dx>

mov ah,02h ; функция DOS 02h – вывод символа

mov dl,13 ; CR – возврат каретки

int 21h

mov dl,10 ; LF – перевод строки

int 21h

LoadReg <dx,ax>

endm

Обратите внимание на то, что для сохранения регистров, используемых в макросе NextLine, используются макросы SaveReg и LoadReg, описанные в предыдущем разделе.

    1. Ввод строки произвольной длины

Для ввода с клавиатуры последовательности символов произвольной длины (до 256) используется макрос GetStr, который имеет два формальных параметра – Buf адрес строки, куда будут помещены введенные символы и MaxLen максимальная длина вводимой строки (указывает программист).

Результатом работы макроса после его макровызова будет введенная строка символов по адресу Buf и длина введенной строки в регистре АХ.

GetStr macro Buf,MaxLen

local m,TmpBuf

jmp m

TmpBuf label byte ; временный буфер для функции DOS 0ah

rept MaxLen+3 ; доп. три байта - служебная информация

db ' '

endm

m:

SaveReg <ds,es,dx,cx>

xor cx,cx

mov cs:TmpBuf,MaxLen+1

mov ah,0ah

push ds

pop es

push cs

pop ds

lea dx,cs:TmpBuf

int 21h

mov al,cs:TmpBuf+1

; Пересылка TmpBuf в Buf (для удаления служебных символов):

mov cl,al ; длина введенной строки в al

xor ah,ah ; 0 в ah

lea si,cs:TmpBuf+2 ; откуда - ds:si

lea di,buf ; куда - es:di

rep movsb

LoadReg <cx,dx,es,ds>

endm

1.5 Вывод строки на экран

Для вывода произвольной строки на экран дисплея используется макрос. Макрос имеет один формальный параметр, который при макровызове должен быть заменен на фактический. Для правильной работы макроса необходимо, чтобы выводимая строка заканчивалась символом '$' – признак конца строки в ассемблере.

OutStr macro str

SaveReg <ax,dx>

mov ah,09h

lea dx,str

int 21h

LoadReg <dx,ax>

endm

Задание 1.

Внимательно ознакомьтесь с макросами 1.1 - 1.5. Используя необходимые макросы, напишите программу, которая ожидает ввод строки (конец ввода <Enter>). По окончании ввода программа должна вывести полученную строку на экран, предварительно осуществив перевод строки (т.е. в результате получить две одинаковые строки друг под другом).

; Прототип программы с использованием модели small

include macros.inc ; подключение библиотеки макросов

.model small

.stack 100h

.data

string db 256 dup (‘$’)

.code

start:

mov ax,@data

mov ds,aх ; загрузка сегментного регистра DS

… ; здесь должен быть размещен Ваш код

mov ah,4ch ; выход из

int 21h ; программы

end start

1.6 Пересылка строк

mov_string macro dest,src,len

;На входе идентификаторы: строки-источника - src, строки-приемника - dest

;сегментные регистры ds (для источника) и es (для приемника) должны быть ; загружены правильными значениями до вызова макрокоманды

mov cx,len

lea si,src

lea di,dest

rep movsb

endm

1.7 Очистка строки произвольной длины пробелами

null_string macro dest,len

local m,Z_String

;на входе:

;dest - адрес строки

;len - длина очищаемой строки

jmp m

Z_String label byte ;пустая строка

rept len

db ' '

endm

m:

SaveReg <ds,es,cx,si,di>

mov cx,len

push ds

pop es ;адрес dest (приемник) - es:di

push cs

pop ds ;адрес Z_String (источник) - ds:si

lea si,cs:Z_String

lea di,dest

rep movsb

LoadReg <di,si,cx,es,ds>

Endm

1.8 Вывод символа на экран

OutChar macro

;На входе - в dl выводимый символ.

push ax

mov ah,02h

int 21h

pop ax

endm

1.9 Очистка регистра rg

clear_r macro rg

xor rg,rg

endm

1.10 Настройка ds на начало сегмента данных

init_ds macro

mov ax,data

mov ds,ax

xor ax,ax

endm

1.11 Корректный выход из программы

_Exit macro

mov ax,4c00h

int 21h

endm

  1. Использование макроопределений в ассемблерных программах

Задание 2.

Используя результаты, полученные при выполнении первого задания, напишите программу, которая также ожидает ввод строки с клавиатуры, а по окончании ввода заменяет последовательность введенных символов на противоположную и выводит на экран.

Например, вводится строка:

QWERTY12345 <Enter>

Программа должна вывести на экран:

54321YTREWQ.

Пояснение. Для приведенного в задании 2 примера после выполнения макровызова

GetStr string,20 символы строки расположатся следующим образом: string[0] = Q

string[1] =W

string[2] =E

string[3] =R

string[4] =T

string[5] =Y

string[6] =1

string[7] =2

string[8] =3

string[9] =4

string[10] =5,

а в регистре АХ будет число введенных символов АХ=11.

Введите еще одну переменную (например. string1 db 256 dup (‘$’) ), в которую перепишите строку string, начиная с последнего символа к первому. После чего выведите string1 на экран дисплея.

Литература

1. Конспект лекций.

2. Юров В. ASSEMBLER. Учебник. «Питер», 2001.

Соседние файлы в папке 3
  • #
    15.03.2015532 б632.asm
  • #
    15.03.201520.87 Кб532.LST
  • #
    15.03.2015232 б532.MAP
  • #
    15.03.2015816 б632.OBJ
  • #
    15.03.2015559 б6322.asm
  • #
    15.03.201573.22 Кб9laba_ass_03.doc
  • #
    15.03.20156.96 Кб7MACROS.INC
  • #
    15.03.20151.48 Кб9tasm.txt
  • #
    15.03.20151.5 Кб7tlink.txt