Для кратковременного хранения данных используют **регистры** - ячейки, расположенные в центральном процессоре и доступные из машинных программ. Доступ к регистрам осуществляется намного быстрее, чем к ячейкам оперативной памяти. Все регистры имеют размер слова - 16 разрядов, за каждым из них закреплено имя.  
По назначению и способу использования регистры делятся на группы: 
- Регистры общего назначения
- Сегментные регистры
- Указатели команд 
- Регистр флагов
## Регистры общего назначения
- **AX** - аккумулятор
- **BX** - база
- **CX** - счетчик
- **DX** - данные
- **SI** - индекс источника
- **DI** - индекс приемника
- **BP** - указатель базы
- **SP** - указатель стека
  
Первые 4 регистра (AX, BX, CX, DX) устроены таким образом, что возможен независимый доступ к их старшим (H) и младшим (L) половинам. Целиком регистр используется при работе с числами, а их половины - при работе с частями чисел и символами. Регистры SI, DI, BP и SP предназначены для чтения и записи целиком.  
![Регистры общего назначения](../Pictures/02_01.%20Регистры%20общего%20назначения.png)  
Особенностью всех регистров общего назначения является то, что их можно использовать в любых арифметических, логических и других машинных операциях.  
Если в команде операнд берется из памяти, то ссылаться на него можно, указав некоторый адрес и некоторый регистр. В этом случае команда будет работать с так называемым исполнительным адресом, который вычисляется, как сумма адреса, указанного в команде, и текущего значения, указанного в регистре. Этот процесс называется **модификацией адреса**, а используемый при этом регистр - **модификатором**. Ими могут быть только 4 регистра: BX, BP, SI, DI. Модифицировать адрес можно по двум регистрам сразу, но только так, что один из регистров - это BX или BP, а другой - SI или DI.
## Сегментные регистры
- **CS** - сегмент команд
- **DS** - сегмент данных
- **SS** - сегмент стека
- **ES** - дополнительный сегмент
  
Сегменты по 16 бит, не разделяются.  
![Сегментные регистры](../Pictures/02_02.%20Сегментные%20регистры.png)  
В арифметических и логических операциях эти регистры не участвуют. Эти регистры участвуют в сегментировании адресов. Если в ЭВМ используется память большого объема, тогда для ссылок на ее ячейки приходится использовать длинные адреса, а так как эти адреса указываются в командах, то и команды оказываются длинными.  
Сократить размеры команд можно, используя сегментирование. Любой адрес $A$ можно представить как сумму $B$ и $d$: $A=B+d$, где $B$ - начальный адрес сегмента памяти, где находится ячейка $A$, а $d$ - это смещение.  
Если сегменты памяти небольшие, то и смещение $d$ будет небольшим, поэтому большая часть длинного адреса будет сосредоточена в $B$. Если в команде необходимо указать адрес $A$, то тогда часть $B$ этого адреса записываем в определенный регистр, и в команде вместо $A$ указываем этот регистр и смещение $d$. Благодаря модификации адресов, данная команда будет работать с адресом, равным сумме смещения $d$ и содержимого регистра.  
Размеры сегментов памяти не должны превышать 64 Кб = $2^{16}$ байт, т. е. смещение - это 16-разрядные адреса. Именно их принято использовать в программировании: 0000h - FFFFh.  
В регистре CS находится начальный адрес сегмента команд. Соответственно, в регистре DS находится начальный адрес сегмента данных. SS указывает на начало стека. Тогда, при ссылках на эти сегменты, в командах соответствующие сегментные регистры не указываются, они подразумеваются по умолчанию.
## Указатель команд
- **IP** - указатель команд
  
![Указатель команд](../Pictures/02_03.%20Указатель%20команд.png)  
В регистре IP всегда находится адрес команды, которая будет выполнена следующая. Поэтому, абсолютный адрес этой команды определяются парой регистров CS и IP. Изменения любого из этих регистров - это переход. Поэтому содержимое CS и IP можно менять только командами перехода.
![Запись адресов команд в регистры](../Pictures/02_04.%20Запись%20адресов%20команд%20в%20регистры.png)  
## Регистр флагов
**Флаг** - это бит принимающий значение 1, если выполнено некоторое условие, и 0, если условие не выполнено (флаг сброшен).  
В процессоре 8086 используются 9 флагов, собранных в 16-разряднный регистр **Flags**.  
![Регистр флагов](../Pictures/02_05.%20Регистр%20флагов.png)  
Флаги делятся на 2 группы:  
1. **Флаги условий** - автоматически меняются при выполнении команд и фиксируют те или иные свойства результата:
	- **CF** - флаг переноса. Используется в арифметических операциях над числами без знака
	- **OF** - флаг переполнения. Используется в арифметических операциях над числами со знаком. OF=1 - переполнение мантиссы
	- **ZF** - флаг нуля. ZF=1, если результат операции равен нулю
	- **SF** - флаг знака. SF=1, если в операции над знаковыми числами получился отрицательный результат
	- **PF** - флаг четности. PF=1, если в 8 младших битах результата содержится четное количество двоичных единиц. Учитывается только в операциях ввода-вывода
	- **AF** - флаг дополнительного переноса. Фиксирует особенности выполнения операций над двоично-десятичными числами
2. **Флаги состояний** - эти флаги меняет сама программа, а их состояние оказывает влияние на дальнейшую работу процессора:
	- **DF** - флаг направления. Устанавливает направление просмотра строк в строковых командах. DF=0 - строки просматриваются вперед, DF=1 - в обратном направлении
	- **IF** - флаг прерываний. IF=0 - процессор перестает реагировать на поступающие к нему прерывания. IF=1 - блокировка прерываний снимается
	- **TF** - флаг трассировки. При TF=1 после выполнения каждой команды процессор делает прерывание, т. е. останавливается, чем можно воспользоваться для отладки программы
## Представление данных и команд
В процессоре 8086 делается различие между целыми числам без знака и со знаком.  
Целые числа без знака:
- Байт: 0 - 255 ($2^8-1$)
- Слово: 0 - 65535 ($2^{16}-1$)
- Двойное слово : 0 - 4294967295 ($2^{32}-1$)
  
Числа размером в слово и двойное слово, хранятся в памяти в перевёрнутом виде. Это сделано для удобства сложения и вычитания. Однако, в регистре числа размером 100 хранятся в нормальном виде.  
![Хранение числа 98 в памяти](../Pictures/02_06.%20Хранение%20числа%2098%20в%20памяти.png)  
Целые числа со знаком:
- Байт: -128 - +127
- Слово: -32768 - +32767
- Двойное слово: -2147483648 - +2147483647
  
Знаковые числа записываются в дополнительном коде. Неотрицательное число записывается как беззнаковое: +98=62h-0062h. А отрицательное число представляется беззнаковым числом $2^k-|x|$, где $k$ - количество разрядов в ячейке, отведенное под число: -98=9Eh=FF9Eh (158=256-98, $2^{16}$-98=10000h-62h).  
#### Символьные данные
Символьные данные в памяти ЭВМ хранятся в двоичном виде. Для этого каждому символу ставится в соответствие некоторое неотрицательное число, называемое кодом символа. Конкретное соответствие между символами и их кодами называется **системой кодировки**. В ЭВМ, как правило, используются 8-разрядные коды символов. Это позволяет закодировать 256 символов. Обычно используется система кодировки **ASCII**. Под каждую строку отводят нужное количество соседних байтов, которые записывают коды символов образующих строку. Адресом строки считается адрес его первого байта. 
