Использование ДУА в макросах
Пример 1. Опишем в виде макроса операцию сдвига значения переменной x на n разрядов вправо. n – явно заданное положительное число. Макрорасширение должно содержать минимально возможное число команд. Это можно сделать так: shift macro x, n Обращения: shift A, 5 ; x = A, n = 5 ife n – 1 ; n – 1 = 0 ? После макрогенерации: shr x, 1 mov CL, 5 else ; n > 1 shr A, CL mov CL, n shr x, CL endif endm Пример 2.Константное выражение в if и ife может быть любым, но так как оно вычисляется на этапе макрогенерации, в нем не должно быть ссылок на величины, которые станут известными только при выполнении программы. Например, в константных выражениях не должно быть ссылок на регистры и ячейки памяти, не должно быть ссылок вперед. Константное выражение должно быть вычислено макрогенератором при первом проходе. Константное выражение часто бывает логическим, в нем могут использоваться операторы отношения: EQ, NE, LT, LE, GT, GE и логические операторы NOT, OR, XOR. Запишем в виде макроса SET_0 x операцию x = 0, если x – переменная размером в байт, слово или двойное слово. SET_0 macro x if type x EQ dword mov dword ptr x, 0 elseif type x EQ word mov word ptr x, 0 else mov byte ptr x, 0 endif endm Пример 3.Напишем еще одно макроопределение для сдвига вправо на n разрядов значения байтовой переменной B. Учтем, что при n = 0 сдвига нет и макрорасширение не должно появиться в тексте программы, а при n > 7 результат сдвига – это 0, поэтому сдвиг можно заменить записью нуля в B. Set_0 macro B, n if (n GT 0) AND (n LT 8) ;; 0 < n <8 mov CL, n shr b, CL else if n GE 8 ;; n >= 8 mov B, 0 endif endif endm Пример 4 использование ifidn и ifdif. Поиск max или min из двух знаковых величин, хранящихся в байтовых регистрах, т.е. вычислить R1 = T (R1, R2),где T – это max или min, причем, должно генерироваться непустое макрорасширение только если R1 и R2 – это разные регистры. Если обращение к макросу будет Max_Min R1, R2, T, то необходимо проверять несовпадение первых двух параметров. И чтобы один макрос вычислял и max и min, нужно проверять и значение третьего параметра. Макрос может быть таким: Max_Min macro R1, R2, T Local L ifdif <R1>, <R2> ;; R1 и R2 – разные регистры Cmp R1, R2 ifidn <T>, <max> ;; T = max ? Jge L Else Jle L Endif Mov R1, R2 L: endif Endm Макрокоманда Max_Min AL, BH, MIN приведет к следующим действиям макрогенератора: (пусть метка L заменилась меткой вида ??0110) ---------------------------- ifdif <AL>, <BH> cmp AL, BH в исходном тексте cmp AL, BH ifidn <MIN>, <MAX> программы ifidn <MIN>, <MAX> jge ??0110 окажется jge ??0110 else cmp AL, BH else jle ??0110 jle ??0110 jle ??0110 endif mov AL, BH endif mov AL, BH ??0110: mov AL, BH ??0110: ---------------------- ??0110: ---------------------------- endif
26) Многомодульные программы в Ассемблере, директивы для организации межмодульных связей Предположим, что есть модуль, содержащий процедуры ввода и вывода символов и строк, который подключается к основной программе на этапе редактирования: Masm p.asm, p.obj, p.list link p.obj + ioproc.obj, p.exe P.exe Есть файл io.asm, содержащий описания макросов обращения к этим процедурам. Этот файл подключается на этапе ассемблирования с помощью директивы include io.asm. Для иллюстрации организации многомодульной программы решим задачу: ввести текст не более, чем из 100 символов, заканчивающийся точкой и вывести его в обратном порядке, заменив прописные буквы на строчные. Пусть программа состоит из двух модулей - головного и вспомогательного. Во вспомогательном описывается переменная EOT, значением которой является символ конца ввода текста, и процедура LOWLAT, заменяющую прописную на строчную. Головной модуль должен вводить текст, записывать его в массив в обратном порядке, обращаясь к процедуре LOWLAT для замены больших букв на малые, а затем выводить этот массив на экран. ; вспомогательный модуль Public EOT, LOWLAT D1 segment EOT DB ‘.’ ; символ конца ввода D1 ends C1 segment Assume CS: C1 LOWLAT proc far ; процедура перевода больших букв в малые, ; на входе (AL) – любой символ, на выходе (AL) – малая буква cmp AL, ‘A’ ; AL < ‘A’ или AL > ‘Z’, то nolat Jb nolat cmp AL, ‘Z’ Ja nolat add AL, - ‘A’ + ‘a’ Nolat: ret LOWLAT endp C1 ends End
; головной модуль include io.asm extrn EOT: byte, LOWLAT: far s segment stack DB 256 dup (?) s ends d segment txt DB 100 dup (?), ‘$’ d ends c segment assume SS: s, DS: d, CS: c start: mov AX, d mov DS, AX ; DS = d для доступа к TXT mov AX, seg EOT mov ES, AX ; ES = D1 для доступа к EOT mov SI, 100 OutCH ‘>’ ; приглашение к вводу символа
inp: InCH AL ; ввод символа cmp AL, ES:EOT ; если достигнут конец ввода je PR ; то PR call LOWLAT ; замена символа dec SI mov TXT[SI], AL jmp inp PR: lea DX, TXT[SI] ; вывод OutSTR ; на экран TXT Finish c ends end start В основной программе OutCH <параметр> и InCH <параметр> - макрокоманды ввода и вывода на экран параметра OutSTR - макрокоманда вывода строки Finish macro ; макрос окончания счета mov AH, 4Ch int 21h endm
2) Передача параметров в подпрограммы по ссылке и по значению, организация рекурсивных подпрограмм При передаче параметров по значению процедуре передается значение фактического параметра, оно копируется в ПП, и ПП использует копию, поэтому изменение, модификация параметра оказывается невозможным. Этот механизм используется для передачи параметров небольшого размера. Например, нужно вычислить c = max (a, b) + max (7, a-1). Здесь все числа знаковые, размером в слово. Используем передачу параметров через регистры. Процедура получает параметры через регистры AX и BX, результат возвращает в регистре AX. Процедура: AX = max (AX, BX) max proc cmp AX, BX jge met1 mov AX, BX met1: ret max endp Фрагмент вызывающей программы: ---------------------------------- ; c = max (a,b) + max (7, a-1) mov AX, a mov BX, b call max ; AX = max (a,b) mov c, AX ; c = max (a,b) mov AX, 7 mov BX, a Dec BX call max ; AX = max (7, a-1) add c, AX
Популярное: Как распознать напряжение: Говоря о мышечном напряжении, мы в первую очередь имеем в виду мускулы, прикрепленные к костям ... Почему двоичная система счисления так распространена?: Каждая цифра должна быть как-то представлена на физическом носителе... Как выбрать специалиста по управлению гостиницей: Понятно, что управление гостиницей невозможно без специальных знаний. Соответственно, важна квалификация... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (504)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |