Ограничение области видимости для меток
Применение команд, описанных в данной главе, предполагает довольно интенсивное использование меток. На определенном этапе работы многие программисты типовые фрагменты кода берут из ранее разработанных программ, реализуя своеобразное фрагментарно-модульное программирование. При этом может оказаться, что фрагменты кода имеют одинаковые метки. Что делать — пересматривать весь текст? Если не проанализировать код с должным вниманием, потом можно провести много часов за работой с отладчиком или, что еще хуже, программа начнет неправильно работать у заказчика. Поэтому полезными могут оказаться некоторые средства работы с метками, описанные в этом разделе.
Пакет TASM поддерживает директиву LOCALS, разрешающую использовать в программе локальные блоковые метки. Формат директивы:
LOCALS [символ_префикса]
Операнд символ_префикса определяет двухсимвольное имя, которое впоследствии потребуется при автоматическом формировании меток в качестве их первых символов. По умолчанию в качестве символа префикса используется двух-символьная комбинация @@.
Благодаря механизму локальных блоковых меток можно в пределах одной программы, но в разных блоках, использовать одинаковые метки. В качестве блока здесь понимаются две конструкции — процедуры и фрагменты программы между двумя обычными метками. Структурно вариант с процедурами выглядит так:
model small
.data
…
LOCALS ;@@ - префикс локальных меток по умолчанию
prod proc
prod endp
proc2 proc
@@ml:
…
proc2 endp
.code
…
Область видимости локальных блоковых меток также можно ограничить обычными метками. Для примера возьмем фрагмент последней программы и поставим в ней бессмысленные с точки зрения логики, но наглядные в контексте нашего обсуждения локальные блоковые метки:
LOCALS
;…
<16> mov cx,5
<17> cycl_l:
<18> @@ml: jmp @@ml
;…
<21> cyci_2:
@@ml: jmp @@ml
;…
<25> no_zero:
@@ml: jmp @@ml
;…
Результат трансляции будет положительным, одноименные локальные блоковые метки @@ml будут интерпретированы транслятором как разные. Пакет MASM также поддерживает механизм определения локальных блоковых меток, позволяя определить три ближние метки с предопределенными именами: @@, @F и @В. Между этими метками существует связь. Определение метки с именем @@ указывает транслятору на необходимость заменить ее уникальной меткой в форме @@хххх, где хххх — уникальное в пределах текущей программы шестнадцатеричное значение. После того как такая метка определена, на нее можно ссылаться с помощью неизменяемых меток @F и @В:
;…
@@:
jmp@F ;ссыпка на предыдущую метку @@ (наверх)
jmp@B ;ссылка на следующую метку @@ (вниз)
;…
Итоги
Язык ассемблера (система команд процессора) имеет довольно полный и гибкий набор средств организации всевозможных переходов как в пределах текущего сегмента кода, так и во внешние сегменты.
При организации безусловных переходов возможны переходы как с потерей (JMP), так и с запоминанием (CALL) информации о точке передачи управления.
Принцип работы команд условного перехода основан на том, что процессор по результатам выполнения некоторых команд устанавливает определенные флаги в регистре Е FLAGS/FLAGS. Команды условного перехода анализируют состояние этих флагов и инициируют передачу управления, исходя из результатов анализа.
Система команд процессора допускает программирование циклов со счетчиком. Для этого используется регистр ЕСХ/СХ, в который до входа в цикл должно быть загружено значение счетчика цикла.
Удобство работы с метками в программе можно повысить, если использовать локальные блоковые метки. Такую возможность предоставляют оба пакета ассемблера: TASM и MASM.