При описании команд, необходимо указывать какие операнды в ней допустимы, а какие нет.

| Местонахождение операнда     | Обозначение  | Запись на ассемблере  |
| ---------------------------- | ------------ | --------------------- |
| В команде                    | i8, i16, i32 | Константное выражение |
| В регистре общего назначения | r8, r16      | Имя регистра          |
| В сегментном регистре        | sr           | CS, DS, SS, ES        |
| В памяти                     | m8, m16, m32 | Адресное выражение    |
## Команды пересылки
1. `MOV op1,op2` - по этой команде на место первого операнда пересылается значение второго операнда. Флаги команда не меняет.

```asm
MOV AX, 500 ; AX := 500
MOV BL, DH ; BL := DH
```

```asm
MOV AX, 100
MOV DS, AX
```
Запрещено пересылать из одной ячейки памяти в другую, из одного сегментного регистра в другой, и записывать непосредственный операнд в сегментный регистр.

| op1           | op2                                |
| ------------- | ---------------------------------- |
| r8            | i8, r8, m8 (пересылка байтов)      |
| m8            | i8, r8                             |
| r16           | i16, r16, m16, sr (пересылка слов) |
| sr (кроме CS) | m16, r16                           |
| m16           | i16, r16, sr                       |
  
Размер пересылаемой величины определяется по типу операндов, указанных в команде. Если известны размеры обоих операндов, то эти размеры должны совпадать, иначе ассемблер зафиксирует ошибку.  
**Пример:**  
```asm
X DB ? ; TYPE X = BYTE
Y DW ? ; TYPE Y = WORD
MOV X, 0 ; (X - байт)
MOV SI, 0 ; (SI - регистр размером в слово)
MOV CH, X ; пересылка байта
MOV DX, AL ; (ошибка: DX - слово, AL - байт)
```
2. Оператор указания типа `PTR`: `<тип> PTR <выражение>`, где `<тип>` - это служебные слова BYTE, WORD, DWORD. Выражение может быть либо константным, либо адресным.
  
Оператор `PTR` используется в двух случаях: 
1) Когда типы операндов неизвестны, и поэтому необходимо явно указать тип одного из них. 
  
**Пример:** В регистре SI находится адрес некоторой ячейки памяти, и требуется записать 0 в эту ячейку.
```asm
MOV BYTE PTR [SI], 0 
MOV WORD PTR [SI], 0   
MOV [SI] BYTE PTR 0
MOV [SI] WORD PTR 0
```
2) Когда необходимо изменить тип, указанный при описании переменной
  
**Пример:** 
```asm
Z DW 1234h ; Z: 34h, Z+1: 12h
MOV BYTE PTR Z, 0 ; Z: 00h, Z+1: 12h
```
3. Команда перестановки двух операндов `XCHG`:
```asm
XCHG
XCHG op1, op2
```
Флаги команда не меняет, операнды должны быть одного размера.

| op1 | op2                          |
| --- | ---------------------------- |
| r8  | r8, m8 (перестановка байтов) |
| m8  | r8                           |
| r16 | r16, m16 (перестановка слов) |
| m16 | r16                          |
  
**Пример:**  
```asm
MOV AX, 62 ; AX = 62
MOV SI, 135 ; SI = 135
XCHG AX, SI ; AX = 135, SI = 62
```
## Арифметические команды
1. **Сложение**: `ADD op1,op2`, **вычитание**:`SUB op1,op2`.

| op1 | op2                                     |
| --- | --------------------------------------- |
| r8  | i8, r8, m8 (сложение/вычитание байтов)  |
| m8  | i8, r8                                  |
| r16 | i16, r16, m16 (сложение/вычитание слов) |
| m16 | i16, r16                                |
  
Меняются флаги переноса CF, переполнение OF, знака SF и нуля ZF.
2. **Увеличение на 1**: `INC op`) **уменьшение на 1**: `DEC op`. Допустимые операнды: `r8`, `m8`, `r16`, `m16`. Команды `INC` и `DEC` не меняют флаг переноса CF и занимают меньше места в памяти.
3. **Изменение знака числа**: `NEG op`. Допустимые операнды: `r8`, `m8`, `r16`, `m16`. Команда рассматривает свой операнд, как число со знаком, и меняет его на противоположный:
```asm
MOV AH, 1
NEG AH ; AH = -1
```
Если операнд равен -128, то операнд не меняется, флаг переполнения OF будет равен 1. Если операнд равен 0, флаг переноса CF будет равен 0, в других случаях - 1.
4. **Сложение с учетом переноса**: `ADC op1, op2`, **вычитание с учетом переноса**: `SBB op1, op2`.
  
`ADC` - к сумме прибавляется значение CF.  
`SBB` - из разности вычитается CF.  
5. **Умножение целых без знака**: `MUL op`, **умножение целых со знаком**: `IMUL op`.
  
Операнд может быть либо в регистре, либо в памяти, но не может быть непосредственным операндом. Местоположение другого операнда фиксировано и явно в команде не участвует. При умножении байтов первый множитель берется из регистра AL, и не из какого другого. При умножении слов берется из регистра AX. Под результат умножения отводится в 2 раза больше места, чем под сомножители. При умножении байтов результат имеет размер слова и записывается в регистр AX (AH - старшие разряды, AL - младшие разряды). При умножении слов результат имеет размер двойного слова и записывается в 2 регистра (DX - старшие разряды, AX - младшие).  
**Пример:**  
```asm
N DB 10
MOV AL, 2
MUL N ; AX = 2 * 10 = 20 = 0014h (AH = 00h, AL = 14h)
MOV AL, 26
MUL N ; AX = 26 * 10 = 260 = 0104h  (AH = 01h, AL = 04h)
MOV AX, 8
MOV BX, -1
IMUL BX ; (DX, AX) = -8 = 0FFFFFFF8h  (DX = 0FFFFh, AX = 0FFF8h)
```
Чтобы узнать, умещается ли результат в формат сомножителей, необходимо проанализировать флаги CF и OF. Если оба флага равны 1, произведение занимает двойной формат. Если оба флага равны 0, то результат произведения байтов занимает регистр AL, а произведение слов - регистр AX.
6. **Деление целых без знака**: `DIV op`, **деление целых со знаком**: `IDIV op`.
  
Операнд - это делитель, который может находится либо в регистре, либо в ячейке памяти. При делении слова на байт, делимое находится в регистре AX. При делении двойного слова на слово, делимое находится в двух регистрах AX и DX.  
В области целых чисел настоящее деление невозможно, и под делением понимают получение двух величин - неполного частного (DIV) и остатка от деления (MOD). Оба этих числа помещаются на место делимого. Старшая часть делимого заменяется на остаток от деления, а младшее - на неполное частное. Неполное частное и остаток имеют одинаковый размер, который совпадает с размером делителя.  
При делении возможно появление ошибки с название "деление на 0" или "переполнение". 2 случай - это когда неполное частное не вмещается в отведенное ему место.  
**Пример с ошибкой:**  
```asm
MOV AX, 600
MOV BH, 2
DIV BH ; 600 DIV 2 = 300, но 300 не вмещается в AL
```
## Изменение размера числа
1. Расширение байта со знаком до слова: `CDW`.
  
`AH := 00h`, если `AL ≥ 0` 
`AH := 0FFh`, если `AL < 0`  
**Пример:**
```asm
MOV AL, 32 ; AL = 20h
CBW ; AX = 0020h (число +32 как слово)
MOV AL, -32 ; AL = 0E0H
CBW  ; AX = 0FFE0h (число -32 как слово)
```

2. Расширение слова со знаком до двойного слова: `CWD`  
  
`DX := 0000h`, если `AX ≥ 0` 
`DX := 0FFFFh`, если `AX < 0`  