Для кратковременного хранения данных используют **регистры** - ячейки, расположенные в центральном процессоре и доступные из машинных программ. Доступ к регистрам осуществляется намного быстрее, чем к ячейкам оперативной памяти. Все регистры имеют размер слова - 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**. Под каждую строку отводят нужное количество соседних байтов, которые записывают коды символов образующих строку. Адресом строки считается адрес его первого байта.