Россия и Беларусь начали и продолжают войну против народа Украины!

Ассемблер. Арифметические инструкции

  Светлана Деменева  | 

  Обновл. 16 Сен 2021  | 

 37905

 ǀ   1 

На этом уроке мы будем разбираться с арифметическими инструкциями в ассемблере на примере INC, DEC, ADD, SUB и пр.

Инструкция INC

Инструкция INC (от англ. «INCREMENT») используется для увеличения операнда на единицу. Она работает с одним операндом, который может находиться либо в регистре, либо в памяти.

Синтаксис инструкции INC:

INC место_назначения

Операндом место_назначения может быть 8-битный, 16-битный или 32-битный операнд.

Пример:

Инструкция DEC


Инструкция DEC (от англ. «DECREMENT») используется для уменьшения операнда на единицу. Она работает с одним операндом, который может находиться либо в регистре, либо в памяти.

Синтаксис инструкции DEC:

DEC место_назначения

Операндом место_назначения может быть 8-битный, 16-битный или 32-битный операнд.

Пример:

Инструкции ADD и SUB

Инструкции ADD и SUB используются для выполнения простого сложения/вычитания двоичных данных размером один byte, word или doubleword, то есть для сложения или вычитания 8-битных, 16-битных или 32-битных операндов, соответственно.

Синтаксис инструкций ADD и SUB:

ADD/SUB      место_назначения, источник

Инструкции ADD/SUB могут выполняться между:

   регистром и регистром;

   памятью и регистром;

   регистром и памятью;

   регистром и константами;

   памятью и константами.

Однако, как и для других инструкций, операции типа память-в-память невозможны с использованием инструкций ADD/SUB. Операции ADD или SUB устанавливают или сбрасывают флаги переполнения и переноса.

В следующем примере мы спрашиваем у пользователя два числа, сохраняем их в регистрах EAX и EBX, затем выполняем операцию сложения, сохраняем результат в ячейке памяти res и выводим его на экран:

Результат выполнения программы:

Enter a digit:
3
Please enter a second digit:
4
The sum is:
7

Ниже рассмотрен пример, в котором за счет того, что значения переменных для арифметических выражений прописаны в самом коде программы, можно получить код программы короче и проще:

Результат выполнения программы:

The sum is:
7

Инструкции MUL и IMUL


Есть 2 инструкции для умножения двоичных данных:

   инструкция MUL (от англ. «MULTIPLY») обрабатывает данные unsigned;

   инструкция IMUL (от англ. «INTEGER MULTIPLY») обрабатывает данные signed.

Обе инструкции влияют на флаги переноса и переполнения.

Синтаксис инструкций MUL/IMUL:

MUL/IMUL множитель

Множимое в обоих случаях будет находиться в аккумуляторе, в зависимости от размера множимого и множителя, и результат умножения также сохраняется в двух регистрах, в зависимости от размера операндов.

Рассмотрим 3 разных сценария:

Сценарий №1: Перемножаются 2 значения типа byte. Множимое находится в регистре AL, а множителем является значение типа byte в памяти или в другом регистре. Результат произведения находится в AX. Старшие 8 бит произведения хранятся в AH, а младшие 8 бит хранятся в AL:

Сценарий №2: Перемножаются 2 значения типа word. Множимое должно находиться в регистре AX, а множителем является значение типа word в памяти или в другом регистре. Например, для такой инструкции, как MUL DX, вы должны сохранить множитель в DX, а множимое — в AX. В результате получится значение типа doubleword, для которого понадобятся два регистра. Часть высшего порядка (крайняя слева) сохраняется в DX, а часть нижнего порядка (крайняя справа) сохраняется в AX:

Сценарий №3: Перемножаются 2 значения типа doubleword. Множимое должно находиться в EAX, а множителем является значение типа doubleword, хранящееся в памяти или в другом регистре. Результат умножения сохраняется в регистрах EDX и EAX. Биты старшего порядка сохраняются в регистре EDX, а биты младшего порядка сохраняются в регистре EAX:

Пример:

А в следующем примере мы 3 умножаем на 2 и выводим результат:

Результат выполнения программы:

The result is:
6

Инструкции DIV и IDIV

Операция деления генерирует два элемента: частное и остаток. В случае умножения переполнения не происходит, так как для хранения результата используются регистры двойной длины. Однако в случае деления, переполнение может произойти. Если это произошло, то процессор генерирует прерывание.

Инструкция DIV (от англ. «DIVIDE») используется с данными unsigned, а инструкция IDIV (от англ. «INTEGER DIVIDE») используется с данными signed.

Синтаксис инструкций DIV/IDIV:

DIV/IDIV     делитель

Делимое находится в аккумуляторе. Обе инструкции могут работать с 8-битными, 16-битными или 32-битными операндами. Данная операция влияет на все 6 флагов состояния.

Рассмотрим следующие 3 сценария:

Сценарий №1: Делителем является значение типа byte. Предполагается, что делимое находится в регистре AX (16 бит). После деления частное переходит в регистр AL, а остаток переходит в регистр AH:

Сценарий №2: Делителем является значение типа word. Предполагается, что делимое имеет длину 32 бита и находится в регистрах DX и AX. Старшие 16 бит находятся в DX, а младшие 16 бит — в AX. После деления 16-битное частное попадает в регистр AX, а 16-битный остаток — в регистр DX:

Сценарий №3: Делителем является значение типа doubleword. Предполагается, что размер делимого составляет 64 бита и оно размещено в регистрах EDX и EAX. Старшие 32 бита находятся в EDX, а младшие 32 бита — в EAX. После деления 32-битное частное попадает в регистр EAX, а 32-битный остаток — в регистр EDX:

В следующем примере мы делим 8 на 2. Делимое 8 сохраняется в 16-битном регистре AX, а делитель 2 — в 8-битном регистре BL:

Результат выполнения программы:

The result is:
4


Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (33 оценок, среднее: 4,61 из 5)
Загрузка...

Комментариев: 1

  1. Артём:

    Подскажите пожалуйста, а как можно поместить число в 2 регистра, чтобы умножить или поделить? И как получить результат умножения из 2 регистров сразу?

Добавить комментарий

Ваш E-mail не будет опубликован. Обязательные поля помечены *