assembler. Учебник для вузов_Юров В.И_2003 -637с (862834), страница 53
Текст из файла (страница 53)
Поэтому полезными могут оказаться некоторые средства работы с метками, описанные в этом разделе.Пакет TASM поддерживает директиву LOCALS, разрешающую использоватьв программе локальные блоковые метки. Формат директивы:LOCALS [символ_префикса]Операнд символ_префикса определяет двухсимвольное имя, которое впоследствии потребуется при автоматическом формировании меток в качестве их первых символов. По умолчанию в качестве символа префикса используется двухсимвольная комбинация @@.Благодаря механизму локальных блоковых меток можно в пределах одной программы, но в разных блоках, использовать одинаковые метки.
В качестве блоказдесь понимаются две конструкции — процедуры и фрагменты программы междудвумя обычными метками. Структурно вариант с процедурами выглядит так:modelsmall.data'LOCALSprodprocprodproc2@@ml:endpprocproc2.codeendp;@@ - префикс локальных меток по умолчаниюИтоги235Область видимости локальных блоковых меток также можно ограничить обычными метками.
Для примера возьмем фрагмент последней программы и поставимв ней бессмысленные с точки зрения логики, но наглядные в контексте нашегообсуждения локальные блоковые метки:LOCALS<16><17>mov c x , 5cycl_l:<18>@@ml:<21>cyci_2:@@ml:jmp @@ml<25>no_zero:@@ml:jmp @@mlj m p @@mlРезультат трансляции будет положительным, одноименные локальные блоковые метки @@ml будут интерпретированы транслятором как разные.Пакет MASM также поддерживает механизм определения локальных блоковых меток, позволяя определить три ближние метки с предопределенными именами: @@, @F и @В. Между этими метками существует связь.
Определение метки сименем @@ указывает транслятору на необходимость заменить ее уникальнойметкой в форме @@хххх, где хххх — уникальное в пределах текущей программышестнадцатеричное значение. После того как такая метка определена, на нее можно ссылаться с помощью неизменяемых меток @F и @В:]mp@Fjmp@B;ссыпка на предыдущую метку @@ (наверх);ссылка на следующую метку @@ (вниз)Итоги1? Язык ассемблера (система команд процессора) имеет довольно полный и гибкий набор средств организации всевозможных переходов как в пределах текущего сегмента кода, так и во внешние сегменты.• При организации безусловных переходов возможны переходы как с потерей(JMP), так и с запоминанием (CALL) информации о точке передачи управления.» Принцип работы команд условного перехода основан на том, что процессор порезультатам выполнения некоторых команд устанавливает определенные флагив регистре Е FLAGS/FLAGS.
Команды условного перехода анализируют состояние этихфлагов и инициируют передачу управления, исходя из результатов анализа.Ш Система команд процессора допускает программирование циклов со счетчиком. Для этого используется регистр ЕСХ/СХ, в который до входа в цикл должнобыть загружено значение счетчика цикла.• Удобство работы с метками в программе можно повысить, если использоватьлокальные блоковые метки. Такую возможность предоставляют оба пакета ассемблера: TASM и MASM.Глава 11Программированиетиповых управляющихструктурПрограммирование операторов условного перехода if-elseПрограммирование операторов выбора switchПрограммирование операторов цикла while, do-while и forЯзык ассемблера — язык машинных команд. Он поддерживает лишь базовые механизмы организации программ.
В нем отсутствуют управляющие конструкции,естественные для языков высокого уровня. Речь идет о поддержке конструкцийтипа операторов выбора, организации циклов и т. п. В прошлой главе мы положили начало обсуждению этих вопросов, рассмотрев принципы организации цикловв программах на ассемблере. Цель данной главы — разработать шаблоны управляющих конструкций на ассемблере, аналогичные типовым операторам языка высокого уровня.Поступим просто — откроем любой учебник по языку С или C++, составим список приведенных в нем управляющих операторов и покажем способы их реализации на ассемблере. Типовой список будет следующим:в операторы выбора:П условный оператор if-else;П переключатель switch;W операторы цикла:П цикл с предусловием while;П цикл с постусловием do-while;П итерационный цикл for;операторы continue и break.Оператор выбора switch237Условный оператор if-elseУсловный оператор if-else используется для принятия решения о дальнейшем путиисполнения программы.
Синтаксис условного оператора в нотации языков С и C++:if (выражение)оператор_1;elseоператор_2Алгоритм работы условного оператора — вычисляется логическое значениевыражения: если оно истинно, то выполняется оператор_1, в противном случае —оператор_2.В общем случае условный оператор может состоять из одного блока if (без блока else):if(выражение)оператор_1;В программе на ассемблере данные варианты условного оператора можно реализовать следующим образом:;короткий вариант оператора if (выражение) оператор_1;cmp opl,op2 вычисление выраженияjne end if;...;последовательность команд, соответствующая оператор_1endif:;конец короткого условного оператораСтрого говоря, использование команды СМР при реализации условного операторане является обязательным. В данном случае она скорее обозначает место вычислениянекоторого условия в программе, по результатам которого принимается решениео ветвлении.
Вместо данной команды можно использовать любую команду, изменяющую флаг, который будет анализироваться последующим оператором условногоперехода. Эти же рассуждения касаются и команды JNE, вместо которой может стоять требуемая в данном вычислительном контексте команда условного перехода:;полныйcmpjne;...jmpelsel:;...endif:вариант оператора if (выражение) оператор_1; else оператор_2opl,op2 вычисление выраженияelselпоследовательность команд, соответствующая оператор_1endifпоследовательность команд, соответствующая оператор_2;конец полного условного оператораОстается лишь добавить, что приведенные ранее рассуждения о командах СМРи JNE соответствуют также полной форме оператора if.Оператор выбора switchОператор switch (переключатель) в программе на ассемблере можно реализоватьнесколькими способами.
В данной главе мы рассмотрим два наиболее общих и распространенных способа — с использованием команд сравнения и с использованием таблицы. Тем не менее на практике можно встретить и другие способы реализации оператора switch, наиболее полно отражающие условия конкретной решаемойзадачи (см., например [8] и некоторые примеры в данной книге).238Глава 11. Программирование типовых управляющих структурВ нотации языков С и C++ синтаксис оператора switch выглядит так:switch (константное_значение_"выражение") {case константное выражение_1:операнд_1case константное выражение_2:оп.еранд_2default:операнд_с!ет' ault>Простейший способ реализации оператора switch в программе на ассемблерезаключается в организации последовательных сравнений с условными переходами.
К примеру, необходимо обработать три возможные альтернативы в программе, которые идентифицируются целочисленными значениями 1,2,3 ("выражение"):;...формирование константное_значение_"выражение"mov al,константное_значение_"выражение"crop al,l;проверка первой альтернативы (константное выражение_1=1?)]е handle_conditionl;равно, идем на обработкуcmp al,2;проверка второй альтернативы (константное выражение_2=2?)je handle_condition2;равно, идем на обработкуcmp al,3;проверка третьей альтернативы (константное выражение_3=3?)je handle_condition2;равно, идем на обработку;если conditionol | 2 | 3 , то производим обработку по умолчанию;...последовательность команд для обработки по умолчаниюjmp end_switch;уходим на конец s w i t c hhandle_conditionl:последовательность команд для обработки handle_conditionljmp end_switch;уходим на конец s w i t c hhandle_condition2:последовательность команд для обработки handle_condition2jmp end_switch;уходим на конец s w i t c hhandle_condition3:последовательность команд для обработки handle_condition3end_switch:;...;продолжение программыВторой, более элегантный способ реализации конструкции, соответствующейоператору switch, — табличный.
Сразу отмечу, что данный материал логичнее рассматривать после изучения главы 13, посвященной сложным структурам данных.Поэтому, если у вас возникнут трудности с пониманием представленного здесьматериала, пропустите его и вернитесь к нему позже.Для реализации рассматриваемого способа в памяти моделируется некотороеподобие таблицы. Каждая строка таблицы состоит из двух ячеек. Строки таблицырасполагаются в памяти последовательно — друг за другом.
В первой ячейке таблицы располагается значение константное_выражение_п, во второй ячейке — адресперехода, если выполняется условие константное_значение_"выражение" = константное_выражение_п. Целью адреса перехода может быть процедура или метка, соответствующая фрагменту кода, обрабатывающему выполнение условия, заданного в заголовке оператора выбора. Реализация табличным способом приведенногоранее примера будет выглядеть так:.datatable_switchdb 1dw handle_conditionldb 2dw handle_condition2db 3dw handle conditionsОператор выбора switch239.code; •..формирование константное_значение_"выражение"mov al,константное_значение_"выражение"mov bx,offsettable_switchmov cx,3;счетчик циклов=количество альтернативnext_condi tion:cmp al,[bx];проверка очередной альтернативыjne next_;к следующему элементуjmp word ptr [bx+1];на обработку совпаденияadd bx,3;адрес следующей строки таблицы -> bxnext_: loopnext_conditiondefault:если condition<>l|2|3, то производим обработку по умолчаниюпоследовательность команд для обработки по умолчаниюjmp ...;уходим, куда нужноiandle_conditionl:последовательность команд для обработки handle_conditionljmp ...;уходим, куда нужноhandle_condition2:последовательность команд для обработки handle_condition2jmp ...;уходим, куда нужноhandle_condi tion3:последовательность команд для обработки handle_conditionB...jmp ...;уходим, куда нужно;продолжение программыДля лучшего структурирования программы последовательность команд дляобработки условия handle_conditionN можно оформить в виде процедур:.datatable_switchdb 1dw handle_conditionldb 2dw handle_conditionJdb 3dw handle_condition3;адрес процедуры handle_conditionl;адрес процедуры handle_condition2;адрес процедуры handle_condition3handle_conditionlproc;...последовательность команд для обработки handle_conditionlendphandle_condition2proc;...последовательность команд для обработки handle_condition2endphandle_condition3 proc;...последовательность команд для обработки handle_condition3endp.code;..