CodeNet / Языки программирования / Ассемблер / СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
Циклы и переходы ----------------------------------------------------------------- Да этого момента мы рассматривали выполнении процессором 8086 инструкций в строгой последовательности. При этом каждая следующая инструкция выполнялась сразу после инструкции по преды- дущему адресу. Рассматривая программу: . . . mov ax,[BaseCount] . . . push ax . . . мы могли быть совершенно уверены, что инструкция ADD выполнится непосредственно после инструкции MOV, а несколько позднее будет выполнена инструкция PUSH. Если бы этим ограничивалось все, на что способен процессор 8086, то такой компьютер был бы довольно примитивен. Фундамен- тальным свойством любого полезного компьютера является наличие инструкций, которые могут выполнять в программе переход (ветвле- ние) на инструкцию, отличную от следующей инструкции в памяти. В такой же степени важна возможность выполнения условного перехода, в зависимости от состояния или результата операции. Набор инструкций процессора 8086 содержит инструкции для обоих видов переходов. Кроме того, предусмотрены специальные инструкции переходов для обеспечения повторяющейся обработки бло- ка кода. Безусловные переходы ----------------------------------------------------------------- Основной инструкцией перехода в наборе инструкций процессора 8086 является инструкция JMP. Эта инструкция указывает процессору 8086, что в качестве следующей за JMP инструкцией нужно выполнить инструкцию по целевой метке. Например, после завершения выполне- ния фрагмента программы: . . . mov ax,1 jmp AddTwoToAX AddOneToAx: inc ax jmp AXIsSet AddTwoToAX: inc ax AXIsSet: . . . регистр AX будет содержать значение 3, а инструкции ADD и JMP, следующие за меткой AddOneToAX, никогда выполнены не будут. Здесь инструкция: jmp AddTwoToAX указывает процессору 8086, что нужно установить указатель инст- рукций IP в значение смещения метки AddTwoToAX, поэтому следующей выполняемой инструкцией будет инструкция: add ax,2 Иногда совместно с инструкцией JMP используется операция SHORT. Для указания на целевую метку инструкция JMP обычно ис- пользует 16-битовое смещение. Операция SHORT указывает Турбо Ас- семблеру, что нужно использовать не 16-битовое, а 8-битовое сме- щение (что позволяет сэкономить в инструкции JMP один байт). Нап- ример, последний фрагмент программы можно переписать так, что он станет на два байта короче: . . . mov ax,1 jmp SHORT AddTwoToAX AddOneToAx: inc ax jmp SHORT AXIsSet AddTwoToAX: inc ax AXIsSet: . . . Недостаток использования операции SHORT (короткий) состоит в том, что короткие переходы могут осуществлять передачу управления на метки, отстоящие от инструкции JMP не далее, чем на 128 бай- тов, поэтому в некоторых случаях Турбо Ассемблер может сообщать вам, что метка недостижима с помощью короткого перехода. К тому же операцию SHORT имеет смысл использовать для ссылок вперед, поскольку для переходов назад (на предшествующие метки) Турбо Ас- семблер автоматически использует короткие переходы, если на метку можно перейти с помощью короткого перехода, и длинные в противном случае. Инструкцию JMP можно использовать для перехода в другой сег- мент кода, загружая в одной инструкции и регистр CS, и регистр IP. Например, в программе: . . . CSeg1 SEGMENT ASSUME CS:Cseg1 . . . FarTarget LABEL FAR . . . CSeg1 ENDS . . . CSeg2 SEGMENT ASSUME CS:CSeg2 . . . jmp FarTarget ; переход дальнего типа . . . CSeg2 ENDS . . . выполняется переход дальнего типа. Если вы хотите, чтобы метка принудительно интерпретирова- лась, как метка дальнего типа, можно использовать операцию FAR PTR. Например, во фрагменте программы: . . . jmp FAR PTR NearLabel nop NearLabel: . . . выполняется переход дальнего типа на метку NearLabel, хотя эта метка находится в том же сегменте кода, что и инструкция JMP. Наконец, вы можете выполнить переход по адресу, записанному в регистре или в переменной памяти. Например: . . . mov ax,OFFSET TestLabel jmp ax . . . TestLabel: . . . Здесь выполняется переход на метку TestLabel, так же, как и в следующем фрагменте: . . . .DATA JumpTarget DW TestLabel . . . .CODE . . . jmp [JumpTarget] . . . TestLabel: . . .