- •Министерство образования и науки
- •Теоретические сведения
- •1.1. Регистры
- •1.1.2. Регистры общего назначения
- •1.1.3. Сегментные регистры
- •1.2. Регистр флагов
- •1.3. Представление данных
- •1.3.1. Целые числа без знака
- •1.3.2. Целые числа со знаком
- •1.3.3. Представление символьных переменных
- •1.4. Лексемы
- •1.4.1. Идентификаторы
- •1.4.2. Целые числа
- •1.4.3. Символьные данные
- •1.5. Предложения
- •1.5.1. Комментарии
- •1.5.2. Команды
- •1.5.3. Директивы
- •1.6. Директивы определения данных
- •1.6.1. Директива db
- •1.6.2. Директива dw
- •1.6.3. Директива dd
- •1.6.4. Директивы эквивалентности и присваивания
- •1.7. Выражения
- •1.8. Обозначения
- •1.9. Команды пересылки
- •1.9.1. Команда mov
- •1.9.2. Команда xchg (exchange)
- •1.10. Команды сложения и вычитания
- •1.10.1. Особенности сложения и вычитания целых чисел в пк
- •1.10.2. Команды сложения и вычитания
- •Например: Mov ah, 1
- •1.11. Команды умножения и деления
- •1.11.1. Команды умножения
- •1.11.2. Команды деления
- •1.12. Изменение размеров числа
- •Задание
- •Контрольные вопросы
- •Литература
1.7. Выражения
Выражения в ЯА могут состоять только из констант и чисел. Вычисления осуществляются на этапе трансляции по модулю 216(от 2-15до 2-16-1).
Операции, применяемые в выражениях:
Одноместные плюс и минус +К, -К
Операторы сложения и вычитания К1+К2, К1-К2
Операторы умножения и деления: K1K2, K1K2, K1 MOD K2 (MOD-остаток от деления).
Важно заметить, что если X,Y-переменные, то X-Y - это не разность между значениями переменных, а разность между их адресами;
Например: X DB 3, 5
Y DB 15
Z DB Y-X ; Z=2
1.8. Обозначения
Для сокращения записи операндов будем использовать след обозначения:
i18, i16, i32 константное выражение
r8, r16 регистр общего назначения
Sr сегментный регистр CS, DS, SS, ES
m8, m16, m32 ячейка памяти (адресное выражение)
1.9. Команды пересылки
1.9.1. Команда mov
Синтаксис: MOV <op1>, <op2>
По этой команде значение ор2 пересылается в ор1: ор1=ор2. Флаги эта команда не меняет. Допустим след комбинации операндов:
Op1 |
Op2 |
r8 m8 r16 Sr(кроме Cs) m16 |
i8,r8,m8 i8,r8 i16,r16,sz,m16 r16,m16 i16,r16,Sr |
Замечание: из таблицы видно, что запрещены пересылки из одной ячейки в другую, из одного сегментного регистра в другой, запись константы в сегментный регистр.
Замечание: в ПК числа размером в слово хранятся в памяти в «перевёрнутом» виде, а в регистрах - в нормальном виде. Команда MOV учитывает это и при пересылки слов между памятью и регистрами сама «переворачивает» их.
Как правило, команде MOV легко узнается тип (размер) одного из операндов, он и определяет размер пересылаемой величины. Иногда бывает необходимым явно указать тип одного из операндов команды. Это можно сделать с помощью оператора PTR (от pointer, указатель).
Синтаксис:
<тип> PTR <выражение>,
где <тип>-это Byte, Word или Dword, а <выражение> может быть константа или адресным.
Пример: Z DW 1110 h ; z 10h|11h
mov byte ptr Z, 0; z 0 |11r z=1100h
1.9.2. Команда xchg (exchange)
Синтаксис: XCHG <op1>, <op2>
Команда меняет местами значения своих операторов (они должны быть либо словами, либо байтами). Флаги при этом не меняются.
Пример: Movax,62 ; Ax=62
Mov Si,135 ; si =135
XCHG Ax,Si ; Ax=135 Si=62
Допустимые значения операндов команды XCHG:
-
Ор1
Op2
r8
m8
r16
m16
r8, m8
r8
r16,m16
r16
Как видно, не допускается перестановка содержимого двух ячеек памяти.
1.10. Команды сложения и вычитания
1.10.1. Особенности сложения и вычитания целых чисел в пк
Что произойдет, если, например, при ячейке размером в 8 байтов мы складываем 250 и 10. Результат (260, или 100000100 в) не «влезет» в байт. В этом случае в ПК ошибка не фиксируется (программа не прерывается), левая единица (единица переноса) отбрасывается и в качестве ответа выдаётся искаженная сумма (00000100 в , т.е. 4). Но зато во флаг переноса CF записывают 1.
Такое суммирование с отбрасыванием единицы переноса в математике называется суммированием по модулю 2K (К- размер ячейки), при этом в флаге CF фиксируется, был ли перенос:
При вычитании без знаковых целых чисел также возникает проблема: что делать, если при вычитании X-Y оказалось X<Y? Ведь в этом случае получается отрицательная разность, а это уже вне области без знаковых чисел.
В ПК поступают следующим образом: при X>Y выполняется обычное вычитание, но если X<Y, тогда числу X делается «заём» единицы (к числу X прибавляется величина 2K) и только после этого производится вычитание. Например. При K=8 вычитание 1-2 производится так:
(в двоичной системе замена 1 на 256+1-это замена 00000001 на 100000001, т.е. приписывание 1 слева). При этом ошибка не фиксируется, зато флаг переноса CF заносится 1, что сигнализирует о займе 1 , о неправильном результате.
Такое вычитание в математике называют вычитанием по модулю 2K:
Теперь рассмотрим сложение и вычитание знаковых чисел. Поскольку целые числа со знаком представлены в дополнительном коде, то складывать и вычитать их можно по алгоритмам для беззнаковых чисел. Делается это так: дополнительные коды знаковых операндов рассматриваются как числа без знака и в таком виде их складывают или вычитают, а полученный результат затем рассматривают как дополнительный код знакового ответа.
Пример 1: Сложить +3 и –1 .(K=8)
Доп.(+3)=3. Доп.(-1)=256-1=255.
Складываем (3+255) MOD 256=258 MOD 256=2.Теперь величина 2 рассматривается как доп.код ответа, т.е. +2
Пример 2: Сложить –3 и +1 (К=8)
Доп.(-3)=256-3=253 Доп.(+1)=1.
Складываем: (253+1) MOD 256=254.Теперь рассматриваем эту величину как доп.код ответа, получим результат –2 (254=256-2).
Однако, возможны проблемы! Например, в байте знаковые числа находятся в области от –128 до 127. Рассмотрим сложение знаковых чисел +127 и +2.Складывая их как знаковые числа 127 и 2 , получаем 129. Эту величину надо рассмотреть как дополнительный код: поскольку 129=256-127, то суммой будет считаться –127.
Почему так вышло? При представлении чисел левый разряд считается знаковым (1-«минус», 0-«плюс»), а на модуль числа отводится 7 разрядов справа. У нас не получился ответ 129 =10000001 в, модуль которого не вмещается в эти 7 разрядов, поэтому модуль «залез» в знаковый разряд, изменив его на противоположный. Такое «залезание» модуля (мантиссы, цифровой части) числа на знаковый разряд называется переполнением мантиссы. В общем случае оно происходит , если складывать числа одно знака, и настоящая сумма оказывается вне диапазона представимых знаковых чисел (при К=8 [-128,127]). Переполнение мантиссы фиксируется во флаге переполнения OF: он получает значение 1 , если было переполнение, и 0 иначе.
Аналогичное переполнение возможно и при вычитании, например : (+127)-(-2)=127+2=129, а это дополнительный код числа –127.
Замечание. При сложении и вычитании чисел меняются также флаг нуля ZF и флаг знака SF. Флаг ZF получает значение 1, если результат оказался нулевым, и значение 0 иначе. В флаг CF заносится знаковый (самый левый) бит результата. Этот флаг полезен при работе со знаковыми числами. CF=1, если результат отрицательный.
Пример: 9-9=0 ZF=1 SF=0
8-9=-1 ZF=0 SF=0
9-8=1 ZF=0 SF=0