|
Ушел с форума
16373 / 7685 / 1080
Регистрация: 11.11.2010
Сообщений: 13,759
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 18.12.2013, 14:19 [ТС] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
ГЛАВА 21 Одним из недостатков программирования на языке ассемблера — его чрезвычайная низкоуровневость операций. Например, язык ассемблера может сложить два числа, а вот для сложения трех чисел необходимо писать специальную программу. Такое сведение к операциям низкого уровня приходится делать для любого алгоритма каким бы сложным он не был. В определенной мере этот недостаток устраняется с помощью макросов. Для этого надо в виде макросов описать более крупные операции, а затем составлять программу с использованием этих макросов.МАКРОЯЗЫК (часть 2/3) Примеры использования макросов Пусть в нашей программе переход «если меньше, то». Эта операция реализуется тремя командами:
Предположим, что имеется процедура вычисляющая наибольший общий делитель (NOD). Параметр X передается через регистр AX, параметр Y — через регистр BX, результат Z возвращается через AX. Вычисляем CX=NOD(A,B)+NOD(C,D). На рисунке 58 находится соответствующий фрагмент программы:
При входе в процедуру приходится сохранять в стеке содержимое регистров, для чего многократно записывается несколько команд PUSH, а при выходе из процедуры несколько команд POP. Если в программе много процедур — стоит облегчить себе жизнь, записав эти команды в виде макросов. У этих макросов может быть любое количество фактических параметров (разное количество названий регистров), так как в языке ассемблера можно определять макросы с фиксированным числом формальных параметров, поэтому макрос описывается с одним формальным параметром, но при обращении к нему в макрокоманде указывают через запятую нужное количество фактических параметров и заключают весь список в угловые скобки, в результате получается синтаксически один параметр. В теле макроса от этого списка отделяют по одному настоящему параметру и что-то с ним делают. Макрос должен поставлять в текст программы (в макрорасширение) несколько однотипных команд PUSH R. Здесь воспользуемся блоком повторения:
Определение макроса через макрос Из процедуры можно обращаться к другой процедуре. Аналогично, при описании одного макроса можно ссылаться на другой макрос. Допускается также обращение макроса к самому себе, то есть разрешены рекурсивные макросы. Но на практике рекурсивные макросы встречаются крайне редко. Рассмотрим поэтому нерекурсивное обращение одного макроса к другому.Пусть макрос ARR предназначен для описания массива X из N байтов:
Если бы вместо записи <K> использовалась просто запись K, тогда на первом этапе макроподстановки получилась бы макрокоманда ARR_A,25_MOD_10 с четырьмя операндами, а не с двумя (при макроподстановке уголки фактического параметра отбрасываются и в макрокомандах параметры могут отделяться как запятыми, так и пробелами). При записи <K> уголки заставляют рассматривать эту конструкцию как один параметр: ARR A,<25MOD10>. В языке ассемблера допускается вложенность макроопределений. Но при этом макрос ARR, хотя и описан внутри макроса ARR2, не локализуется в ARR2, и к нему можно обращаться вне макроса ARR2. Но язык ассемблера заметит описание внутреннего макроса только при первом обращении к внешнему макросу.
Директива LOCAL При использовании макросов возникает проблема с метками, которые могут быть помечены предложения тела макроса. Если есть макрос M с внутренней меткой L и в программе имеется n обращений к этому макросу.
Директивы EXITM и GOTO У директивы EXITM нет операндов. Ее можно использовать только внутри макроопределений и блоков повторения (внутри конструкций макроязыка заканчивающихся директивой ENDM). Встретив директиву EXITM макрогенератор завершает обработку ближайшего объемлющего макроопределения или блока повторения.Макрогенератор, создавая первую копию тела блока повторения, перенесет предложение DB 0 в макрорасширение, а затем, встретив EXITM, полностью завершит обработку этого блока, но не покинет тело макроса, а перескочит за ближайшую директиву ENDM. Директива EXITM используется тогда, когда при выполнении некоторого условия надо досрочно, не доходя до ENDM, прекратить макроподстановку или раскрутку блока повторения. Используется в основном в отладочных целях.
Переопределение и отмена макросов Если в тексте программы описать макрос с именем, которым ранее был обозначен другой макрос, то с этого момента прежний макрос считается уничтоженным, а новый макрос действующим:
После директивы PURGE A,INIT к макросам A и INIT уже нельзя обращаться. Условное ассемблирование Условное ассемблирование — это средство для указания программе ассемблеру о трансляции или нетрансляции в объектный код конкретных блоков исходной программы. Если макросы и блоки повторений позволяют избежать многократного выписывания в исходном тексте программы повторяющихся фрагментов, то такое средство макроязыка, как условное ассемблирование, удобно при многократных прогонах программы. Условное ассемблирование позволяет в исходном тексте держать несколько вариантов одного и того же участка программы, а при каждом ее прогоне оставлять в окончательном тексте только один из фрагментов. Какой из вариантов будет оставлен, зависит от тех или иных условий, которые автор программы задает перед прогоном. Автор программы перед каждым прогоном не должен в ручную редактировать текст программы, а возлагает эту работу на макрогенератор. Вы можете в одном тексте программы создать и рабочую программу, и ее демонстрационную версию с ограниченным использованием функций рабочей программы. Возможно также создание в программе интерфейса, поддерживающего несколько языков для общения с пользователем и т.д. и т.п. Программист, изменяя несколько предложений в начале программы, указывает программе-ассемблеру, какие именно куски программы нужно включать в объектную программу для данной системы.Участок программы, затрагиваемый условным ассемблированием, записывается в виде IF-блока:
В IF-директиве указывается некоторое условие, которое проверяется макрогенератором. Если условие выполнено, то макрогенератор оставляет в окончательном тексте программы только фрагмент1, а фрагмент2 исключает, не переносит в окончательный текст. Если же условие не выполнено, тогда фрагмент1 игнорируется, а в окончательную программу вставляется только фрагмент2. Если части ELSE нет, то считается, что пуст фрагмент2, поэтому при невыполнении условия такой IF-блок ничего не вставляет в окончательный текст программы. Так как условие в IF-директиве проверяется на этапе макрогенерации, то в нем не должно быть ссылок на величины, которые станут известными только при выполнении программы (в условии нельзя ссылаться на содержимое регистров или ячеек памяти). Условие должно быть таким, чтобы макрогенератор мог вычислить его сразу, как только встретит его (не должно быть ссылок вперед). Директивы IF и IFE Встречая директиву IF<константное условие> или IFE <константное условие>, макрогенератор вычисляет указанное в ней константное условие. В директиве IF условие считается выполненным, если значение выражения не равно нулю, а в директиве IFE (if equal, если равно) если значение выражения равно нулю.При отладке программы в определенные места текста программы вставляют печать промежуточных значений каких-то переменных, заканчивая отладку, отладочную печать убирают из текста программы. Но если в программе опять появляются ошибки, чтобы их найти, придется снова вставить отладочную печать, а после исправления опять удалить. И этот процесс вставки и удаления отладочной печати может продолжаться долго. Вставлять и удалять отладочную печать можно самим, но если отладочной печати много и если она разбросана по всей программе, то такое изменение текста займет много времени, и здесь легко ошибиться. Понять это может только тот, кто сам прошел через отладочную распечатку своей программы. В подобной ситуации удобно использовать возможности условного ассемблирования: в тексте программы сохраняем отладочную печать, но перед ней указываем условие, что команды отладочной печати должны появляться в окончательном тексте программы, если установлена константа DEBUG EQU 1. Участок исходной программы с отладочной печатью должен выглядеть так:
Допустим, Вы описываете в виде макроса SHIFT X,N сдвиг значения в ячейке X на N разрядов вправо при условии, что параметр X — это имя какой-то переменной, чье значение находится в ячейке [110h], а N — явно заданное положительное число, при условии, что макрорасширение этого макроса должно содержать минимально возможное число байт.
Операторы отношения. Логические операторы
Директивы IFB и IFNB, IFIDN, IFDIF Директивы IFB и IFNB используются для проверки формальных параметров, передаваемых в макрос. При вызове макрокоманды они анализируют значение аргумента, и в зависимости от того, равно оно пробелу или нет, транслируется либо <фрагмент1>, либо <фрагмент2>. В директиве IFB <аргумент> (if blank, если пустой) условие считается выполненным, если значение аргумента равно пробелу, то есть фактический аргумент при вызове макрокоманды не был задан, а в директиве IFNB <аргумент> (if not blank, если не пустой) — если значение аргумента не равно пробелу.
Директивы IFIDN и IFDIF позволяют не просто проверить наличие или значение аргументов макрокоманды, но и выполнить идентификацию аргументов как строк символов. Директива IFIDN сравнивает аргумент1 и аргумент2 как строки символов. Если строки совпадают (identifity -тождество), то транслируется <фрагмент1> иначе <фрагмент2>. Директива IFIDNI — вариант, директивы IFIDN которая игнорирует различие между строчными и прописными буквами. Синтаксис этих директив: IFIDN аргумент1, аргумент2 Директива IFDIF сравнивает аргумент1 и аргумент2 как строки символов. Если строки не совпадают (differnt -другой), то транслируется <фрагмент1> иначе <фрагмент2>. Директива IFDIFI — вариант директивы IFDIF, которая игнорирует различие между строчными и прописными буквами. Синтаксис директив:<фрагмент1> ELSE <фрагмент2> ENDIF IFDIF аргумент-1, аргумент-2
<фрагмент1> ELSE <фрагмент2> ENDIF
0
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Новые блоги и статьи
|
|||
|
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут
Суть:
- Группа наркоманов из 10 человек.
- Только один инфицирован ВИЧ.
- Колются одной иглой.
- Колются раз в день.
- Колются последовательно через. . .
|
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
|
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
|
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . .
а удачный момент так и не приходит.
|
|
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица.
Задача: зафиксировать три левых колонки в отчете.
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
/ / . . .
|
Настройки VS Code
Loafer 13.04.2026
{
"cmake. configureOnOpen": false,
"diffEditor. ignoreTrimWhitespace": true,
"editor. guides. bracketPairs": "active",
"extensions. ignoreRecommendations": true,
. . .
|
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2.
Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива.
Было так:. . .
|
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2.
Задача: реализовать контроль корректности заполнения дат назначения. . .
|