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:
.
.
.
