Inc ассемблер что это
7.1. Сложение и вычитание.
7.1.1. ADD – команда для сложения двух чисел. Она работает как с числами со знаком, так и без знака.
Логика работы команды:
По сути дела, это – команда сложения с присвоением, аналогичная принятой в языке C / C ++:
Операнды должны иметь одинаковый размер. Результат помещается на место первого операнда.
После выполнения команды изменяются флаги, по которым можно определить характеристики результата:
add dx,cx ;DX = DX + CX
add dx,cl ;Ошибка: разный размер операндов.
Логика работы команды:
По сути дела, это – команда вычитания с присвоением, аналогичная принятой в языке C / C ++:
Операнды должны иметь одинаковый размер. Результат помещается на место первого операнда.
На самом деле вычитание в процессоре реализовано с помощью сложения. Процессор меняет знак второго операнда на противоположный, а затем складывает два числа.
sub b x,cl ;Ошибка: разный размер операндов.
7.1.3. Инкремент и декремент. Очень часто в программах используется операция прибавления или вычитания единицы. Прибавление единицы называется инкрементом, а вычитание — декрементом. Для этих операций существуют специальные команды процессора: INC и DEC. Эти команды не изменяют значение флага CF.
Эти команды содержит один операнд и имеет следующий синтаксис:
Логика работы команд:
7.1.4. NEG – команда для изменения знака операнда.
Логика работы команды:
7.2. Сложение и вычитание с переносом.
В системе команд процессоров x86 имеются специальные команды сложения и вычитания с учётом флага переноса (CF). Для сложения с учётом переноса предназначена команда ADC, а для вычитания — SBB. В общем, эти команды работают почти так же, как ADD и SUB, единственное отличие в том, что к младшему разряду первого операнда прибавляется или вычитается дополнительно значение флага CF.
Они позволяют выполнять сложение и вычитание многобайтных целых чисел, длина которых больше, чем разрядность регистров процессора (в нашем случае 16 бит). Принцип программирования таких операций очень прост — длинные числа складываются (вычитаются) по частям. Младшие разряды складываются(вычитаются) с помощью обычных команд ADD и SUB, а затем последовательно складываются(вычитаются) более старшие части с помощью команд ADC и SBB. Так как эти команды учитывают перенос из старшего разряда, то мы можем быть уверены, что ни один бит не потеряется. Этот способ похож на сложение(вычитание) десятичных чисел в столбик.
На следующем рисунке показано сложение двух двоичных чисел командой ADD:
При сложении происходит перенос из 7-го разряда в 8-й, как раз на границе между байтами. Если мы будем складывать эти числа по частям командой ADD, то перенесённый бит потеряется и в результате мы получим ошибку. К счастью, перенос из старшего разряда всегда сохраняется в флаге CF. Чтобы прибавить этот перенесённый бит, достаточно применить команду ADC:
//Сложение двух чисел с учетом переноса: FFFFFFAA + FFFF
Ассемблер. Арифметические инструкции
Обновл. 16 Сен 2021 |
На этом уроке мы будем разбираться с арифметическими инструкциями в ассемблере на примере INC, DEC, ADD, SUB и пр.
Инструкция INC
Инструкция INC (от англ. «INCREMENT») используется для увеличения операнда на единицу. Она работает с одним операндом, который может находиться либо в регистре, либо в памяти.
Синтаксис инструкции INC:
Операндом место_назначения может быть 8-битный, 16-битный или 32-битный операнд.
Инструкция DEC
Инструкция DEC (от англ. «DECREMENT») используется для уменьшения операнда на единицу. Она работает с одним операндом, который может находиться либо в регистре, либо в памяти.
Синтаксис инструкции 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
Ниже рассмотрен пример, в котором за счет того, что значения переменных для арифметических выражений прописаны в самом коде программы, можно получить код программы короче и проще:
Результат выполнения программы:
Инструкции MUL и IMUL
Есть 2 инструкции для умножения двоичных данных:
инструкция MUL (от англ. «MULTIPLY») обрабатывает данные unsigned;
инструкция IMUL (от англ. «INTEGER MULTIPLY») обрабатывает данные signed.
Обе инструкции влияют на флаги переноса и переполнения.
Синтаксис инструкций MUL/IMUL:
Множимое в обоих случаях будет находиться в аккумуляторе, в зависимости от размера множимого и множителя, и результат умножения также сохраняется в двух регистрах, в зависимости от размера операндов.
Рассмотрим 3 разных сценария:
Сценарий №1: Перемножаются 2 значения типа byte. Множимое находится в регистре AL, а множителем является значение типа byte в памяти или в другом регистре. Результат произведения находится в AX. Старшие 8 бит произведения хранятся в AH, а младшие 8 бит хранятся в AL:
Сценарий №3: Перемножаются 2 значения типа doubleword. Множимое должно находиться в EAX, а множителем является значение типа doubleword, хранящееся в памяти или в другом регистре. Результат умножения сохраняется в регистрах EDX и EAX. Биты старшего порядка сохраняются в регистре EDX, а биты младшего порядка сохраняются в регистре EAX:
Команды ассемблера
Опкод add имеет следующий синтаксис:
Выполняет вычисление: приемник = приемник + источник.
Имеются также другие формы:
| приемник | источник | пример |
|---|---|---|
| регистр | регистр | add ecx, edx |
| регистр | память | add ecx, dword ptr [104h] / add ecx, [edx] |
| регистр | значение | add eax, 102 |
| память | значение | add dword ptr [401231h], 80 |
| память | регистр | add dword ptr [401231h], edx |
Эта команда очень проста. Она добавляет значение источника к значение приемника и помещает результат в приемник. Другие математические команды:
Поскольку регистры могут содержать только целочисленные значения (то есть числа, не, с плавающей запятой), результат деления разбит на частное и остаток. Теперь, в зависимости от размера источника, частное сохраняется в eax, а остаток в edx:
| размер источника | деление | частное в. | остаток в. |
|---|---|---|---|
| BYTE (8-bits) | ax / делитель | AL | AH |
| WORD (16-bits) | dx:ax* / делитель | AX | DX |
| DWORD (32-bits) | edx:eax* / делитель | EAX | EDX |
Источник операции деления может быть:
Источник не может быть непосредственным значением, потому что тогда процессор не сможет определить размер исходного операнда.
| команда | AND | OR | XOR | NOT | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Бит источника | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 1 |
| Бит приемника | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | X | X |
| Бит результата | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 0 |
AND (логическое И)устанавливает бит результата в 1, если оба бита, бит источника и бит приемника установлены в 1.
OR (логическое ИЛИ)устанавливает бит результата в 1, если один из битов, бит источника или бит приемника установлен в 1.
XOR (НЕ ИЛИ)устанавливает бит результата в 1, если бит источника отличается от бита приемника.
NOTинвертирует бит источника.
Выполнение операции XOR на этими битами:
Если вы выполните инверсию каждого бита, то получите:
Значит после операции NOT, ecx будет содержать 0000FFFFh.
Команда jz выполнит переход, если ecx = 0.
Вот и конец урока. Надеюсь, этот не был скучным. Следующий урок расскажет вам про подпрограммы.







