## Безусловный переход. Оператор SHORT
Команды перехода не меняют флаги. В ЭВМ используются несколько машинных команд безусловного перехода, но на ассемблере они все обозначаются одинаково: `JMP <метка>`. Определитель тем или иным способом указывает адрес перехода, т. е. адрес команды, которая будет выписана следующей.
#### 1. Прямой переход
В качестве оператора указывается метка той команды, на которую передается управление.
```asm
JMP L
...
L: MOV AX, 0
```
В ЭВМ имеется 2 машинные команды прямого перехода. В одной из них относительный адрес перехода задается в виде байта (**короткий прямой переход**), а в другой команде - в виде слова (**длинный прямой переход**). В этих командах операнд рассматривается как целое число со знаком, поэтому возможен переход и вперед, и назад.  
Встречая символьную команду, ассемблер вычисляет разность между адресом метки и адресом самой команды перехода, и оценивает величину этой разности. Если разность укладывается в байт, то ассемблер формирует команду короткого перехода. Если разность большая - формируется команда длинного перехода. Однако сделать этот выбор ассемблер может, если метка описана до команды перехода. Т. е., метка является ссылкой назад. При ссылке вперед ассемблер не знает адрес метки и на всякий случай формирует команду длинного перехода. Однако, программист может предупредить ассемблер, что переход будет коротким, с помощью оператора `SHORT`, который ставится в команде перехода перед меткой: 
```asm
JMP SHORT L 
```
Если переход оказывается длинным, то ассемблер выдаст ошибку.
#### 2. Косвенный переход
В этом случае в команде перехода указывается не сам адрес перехода, а то место (ячейка или регистр), где находится этот адрес, т. е. содержание регистра/ячейки рассматривается как адрес некоторой команды, по которому и делятся переход.
## Команды сравнения и условного перехода
Команда сравнения: `CMP op1, op2`.  
Условный переход формируется в 2 шага:
1. Сравниваются некоторые величины и соответствующим образом формируются флаги (`CMP`)
2. В зависимости от значений флагов выписывается переход
  
Команда `CMP` аналогична команде `SUB` (вычитание), однако результат никуда не записывается, главный эффект - это установка флагов.  
Команда условного перехода: `Jxx <метка>`.  
Все команды условного перехода делятся на 3 группы:
1. Команды, которые ставятся после `CMP` 
  
В их мнемокодах с помощью определенных букв описывается тот исход сравнения, при котором нужно сделать переход:
- **E** – equal (равно)
- **N** – not (не, отрицание)
- **G** – greater (больше) – для чисел со знаком
- **L** – less (меньше) – для чисел со знаком
- **A** – above (больше) – для чисел без знака
- **B** – below (меньше) – для чисел без знака
  
2. Команды, которые реагируют на значение флага и не используют команду `CMP`
  
|Мнемокод|Условие перехода|
|:-:|:-:|
|JZ|ZF=1|
|JS|SF=1|
|JC|CF=1|
|JO|OF=1|
|JP|PF=1|
|JNZ|ZF=0|
|JNS|SF=0|
|JNC|CF=0|
|JNO|OF=0|
|JNP|PF=0|
  
В этих командах указывается первая буква правого флага. И если переход должен быть выполнен при значении 1, и N, если значение флага равно 0.  
```asm
MOV AL, A
MUL A
JC ERROR ; A * A > 255 (CF = 1) → ERROR
ADD AL, B
JC ERROR ; A * A + B > 255 (CF = 1) → ERROR
MOV C, AL
...
ERROR: ...
```
3. Команда, проверяющая значение регистра счетчика CX
  
```asm
JCXZ <метка> ; (if cx := 0 then goto <метка>)
```
## Команды управления циклом
#### 1. Команда LOOP
```asm
MOV CX, N ; CX – счетчик цикла
L: ...
... ; тело цикла
DEC CX ; CX := CX - 1
CMP CX, 0 ; CX = 0?
JNE L ; CX <> 0 → L
```
  
```asm
MOV CX, N
L: ...
... ; тело цикла
LOOP L
```
**Пример:** найти N! и записать результат в регистр AX, где N – байтовая переменная.
```asm
MOV AX, 1 ; AX := 1
MOV CL, N ; CX := N как слово (счетчик цикла)
MOV CH, 0 ; CX := N как слово (счетчик цикла)
JCXZ F1 ; N = 0
MOV SI, 1 ; i = 1
F: MUL SI ; (DX, AX) := AX * i (DX = 0)
	INC SI ; i := i + 1
	LOOP F
F1: ...
```
#### 2. команды LOOPE/LOOPZ и LOOPNE/LOOPNZ
`LOOPE <метка>` и `LOOPZ <метка>`.  
**Пример:** записать в регистр BL наименьшее число из отрезка \[2, K\], на которое не делится число N (N и K – байтовые переменные, 2 ≤ K < N) или записать 0, если такого числа нет.
```asm
MOV DL, N
MOV DH, 0
MOV CL, K
MOV CH, 0
DEC CX ; CX := K-1  (счетчик цикла)
MOV BL, 1
DV: INC BL ; очередное число из [2, K]
    MOV AX, DX
    DIV BL ; AH := N mod BL
    CMP AH, 0 ; mod = 0?
    LOOPE DV ; цикл CX раз и пока mod = 0
    JNE DV1 ; mod <> 0 → DV1
    MOV BL, 0 ; нет искомого числа
DV1: ...
```
