
- •Конспект лекций по ассемблеру
- •Структурная схема эвм
- •Организация памяти
- •Порты ввода/вывода
- •Сегментация памяти
- •Логические и физические адреса памяти
- •Адресация команд
- •Адресация данных
- •Адресация сегмента стека
- •Перемещаемые программы
- •Структура микропроцессора
- •Назначение регистров микропроцессора
- •Регистр флагов
- •Ассемблер
- •Выражения
- •Структура машинного оператора
- •Директивы ассемблера
- •Директивы определения данных
- •Определение слова
- •Команды и способы адресации операндов
- •Режимы адресации
- •Команда сложения add
- •Команда сложения с переносом adc
- •Команда вычитания sub
- •Imul – команда умножения со знаком
- •Idiv – команда деления со знаком
- •Команда сравнения cmp
- •Команды безусловного перехода jmp
- •1. Короткий относительный переход
- •2. Внутрисегментный переход
- •Команды условных переходов
- •Знаковые
- •Беззнаковые
- •Специальные
- •Способы адресации
- •Двухоперандные команды
- •Косвенная адресация
- •Регистровая адресация
- •Прямая адресация с индексированием
- •Прямая адресация с базированием
- •Адресация по сумме d8 и индексный регистр
- •Адресация по сумме базового регистра и смещения
- •Адресация с базированием и индексированием
- •Прямая адресация с базированием и индексированием
- •Двухоперандная команда, в которой второй операнд непосредственный
- •Формат двухоперандных команд с акумулятором и но
- •Форматы команды inc
- •Форматы команд pop и push
- •Однобайтные команды без операндов
- •Команды передачи данных mov
- •Команда обмена xchg
- •Команда загрузки исполнительного адреса lea
- •Команды управления циклами команда цикла loop
- •Команды переходов loopz, loope
- •Команды вызова подпрограмм call
- •Структура подпрограммы
- •Команды возврата
- •Передача параметров в процедуру
- •Примеры на обработку матрицы
- •Функции ввода/вывода
- •Функция вызова команды int 21h
- •Вывод на экран дисплея
- •Ввод с клавиатуры
- •Процедура ввода числа форматом слово
Imul – команда умножения со знаком
imul OP – умножение знаковых операндов
-------
Алгоритмы умножения беззнаковых чисел и знаковых чисел отличаются, что потребовало двух команд умножения.
Команда выполняется аналогично mul, при умножении автоматически формируются знак результата. Отличие состоит в правилах формирования флага переполнения/
(-128..127) – диапазон байта.
При выходе результата за диапазон байта формируется переполнение:
15 * 15 = 225 = E1h | (-15) * 15 =-225 =-Е1h=1Fhдк
┌───┐ ┐ | ┌───┐
│ 0F│ AL│ | │ F1│ AL
└───┘ │ | └───┘
* ┌───┐ │ | ┌───┐
│ OF│ BH│ | │ 0F│ BH
└───┘ ├─┐ | └───┘
───────── │ V | ─────────
┌───┬───┐ │ знаковые | ┌───┬───┐
┌───│ 00│ E1│ AX│ величины | │ FF│ 1F│ AX
│ └───┴───┘ ┘ | └───┴───┘
V └─┬─┘ | Если цифровая часть резуль-
CF=1 ┌────────┐ | тата помещается в младшем бай-
OF=1 │11100001│ | те, то все биты старшего байта
└────────┘ можно рассматривать как знаковые разряды. При этом если знаковый разряд младшего байта отличается от любого бита старшего байта, то это указывает на ситуацию переполнения.
┌───┬───┐
│ FF 1F│ AX
└───┴───┘
AX | | AL
┌────────┐ ┌────────┐
│11111111│ │00011111│
└────────┘ └────────┘
|||||||| |
-- - +
Знаки различны и это показывает, что результат не помещается в заданное поле.
CF=1, OF=1.
Как будет выглядеть результат, который помещается:
AX =-100 =-64h = 9Chдк
┌────────┐ ┌────────┐
│11111111│ │10011100│ - значение знакового разряда
└────────┘ └────────┘ в младшем байте совпадает
└┴┴┴┴┴┴┴───┘ со всеми битами старшего разряда, следует CF=0, OF=0, из этого следует, что в качестве результата можно взять только младший байт.
При умножении слова на слово переполнение формируется, если результат выходит за границы диапазона:
(-32768..32767) – т. е. слова со знаком.
DIV – беззнаковое деление
div OP───┬───> ячейка памяти
│ └───> регистр
байт
слово
div BH ──────> AL := AX / BH – частное
------
div BX ──────> AX := ( DX:AX ) / BX – частное
------
╔══════════════════════════════╗
║ Пример на Паскале ║
║ AL := AX div BH - частное ║
║ AH := AX mod BH - остаток ║
║ AX := ( DX:AX ) div BX - чн ║
║ DX := ( DX:AX ) mod BX - ост ║
╚══════════════════════════════╝
Делимое располагается в AX или в регистровой паре DX:AX. Результат записывается в поле делимого. Делимое имеет длину в два раза больше делителя.
Пример
а * b - 2
y = ─────────
c
a db 4h
b db 3h
c db 5h
y db ?
;-----------------------
mov AL,a ;AL:=a
mul b ;AX:=AL * b = a * b
sub AL,2 ;AL:= a * b - 2
;следующим действием необходимо выполнить деление. Делимое
;в регистре AL. При делении используется регистр AX, для это-
;го необходимо, чтобы регистр AH был равен нулю, в общем
;случае.
mov AH,0h ;подготовка к делению беззнаковых чисел
div c ;AH=0h AL=02h - частное
mov y,AL ;занесение в y результата
Подготовка к делению на байт требует занесения в AH нуля. При делении на слово необходимо в DX занести ноль.
Команда деления флаги формирует хаотично. Имеются две критические ситуации:
1) деление на ноль (zero devide) – в этом случае ОС прерывает работу программы выдавая сообщение;
2) переполнение при делении (devided overflow) - прерывание работы программы с выдачей сообщения.
Вторая ситуация возникает при делении большого числа на маленькое:
AX BH
┌───┬───┐ ┌───┐
AL := │ 05│ 2A│ div │ 01│ = 052Ah
└───┴───┘ └───┘
Результат деления не может поместиться в AL, т. е. не представляется возможным сформировать хоть какой-нибудь результат, поэтому программа прерывается с выдачей сообщения.