Арифметика

Целочисленная арифметика

Сложение и вычитание

Инструкция add выполняет сложение двух операндов.

Синтаксис add destination, source. Эквивалентно присваиванию destination += source.

Инструкция sub выполняет вычитание двух операндов.

Синтаксис sub destination, source. Эквивалентно присваиванию destination -= source.

Операндами могут являться регистры, переменные, константы, а также захардкоженные значения. При этом захардкоженные значения не могут быть больше 3232 битов, даже если первый операнд имеет размер в 6464 бита.

mov rax, 5 mov rdx, 2 add rax, rdx ; rax = rax + rdx mov rdx, 3 sub rax, rdx ; rax = rax - rdx ret

Инструкция inc увеличивает операнд на 11.

Синтаксис inc destination. Эквивалентно присваиванию destination += 1.

Инструкция dec уменьшает операнд на 11.

Синтаксис dec destination. Эквивалентно присваиванию destination -= 1.

mov rax, 5 mov rdx, 2 inc rax ; rax = rax + 1 dec rdx ; rdx = rdx - 1 ret

Умножение

Инструкции mul и imul выполняют умножение двух операндов. Инструкция mul выполняет беззнаковое умножение, а инструкция imul выполняет умножение со знаком.

Для imul есть три формата: однооперандный, двухоперандный и трехоперандный. Для mul допустим только однооперандный формат.

Однооперандный формат mul/imul source умножает регистр ax на операнд source, при этом старшие разряды результата помещаются в регистр dx, а младшие разряды результата помещаются в регистр ax.

mul/imul r8/m8ax=alr8/m8\code{\htmlClass{register}{ax}} = \code{\htmlClass{register}{al}} \cdot \code{\htmlClass{register}{r8}/\htmlClass{memory}{m8}};
mul/imul r16/m16dx:ax=axr16/m16\code{\htmlClass{register}{dx}:\htmlClass{register}{ax}} = \code{\htmlClass{register}{ax}} \cdot \code{\htmlClass{register}{r16}/\htmlClass{memory}{m16}};
mul/imul r32/m32edx:eax=eaxr32/m32\code{\htmlClass{register}{edx}:\htmlClass{register}{eax}} = \code{\htmlClass{register}{eax}} \cdot \code{\htmlClass{register}{r32}/\htmlClass{memory}{m32}};
mul/imul r64/m64rdx:rax=raxr64/m64\code{\htmlClass{register}{rdx}:\htmlClass{register}{rax}} = \code{\htmlClass{register}{rax}} \cdot \code{\htmlClass{register}{r64}/\htmlClass{memory}{m64}}.

Двухоперандный формат imul destination, source выполняет умножение destination *= source. Результат усекается до размера операнда-приёмника destination. Если произошло переполнение, то будут установлены флаги CF и OF.

imul r16 r16/m16r16=r16r16/m16\code{\htmlClass{register}{r16}} = \code{\htmlClass{register}{r16}} \cdot \code{\htmlClass{register}{r16}/\htmlClass{memory}{m16}};
imul r32 r32/m32r32=r32r32/m32\code{\htmlClass{register}{r32}} = \code{\htmlClass{register}{r32}} \cdot \code{\htmlClass{register}{r32}/\htmlClass{memory}{m32}};
imul r64 r64/m64r64=r64r64/m64\code{\htmlClass{register}{r64}} = \code{\htmlClass{register}{r64}} \cdot \code{\htmlClass{register}{r64}/\htmlClass{memory}{m64}}.

Трехоперандный формат imul destination, source, immediate выполняет умножение destination = source * immediate. Результат усекается до размера операнда-приёмника destination. Если произошло переполнение, то будут установлены флаги CF и OF.`

imul r16 r16/m16 imm8/imm16/imm32r16=r16/m16imm8/imm16/imm32\code{\htmlClass{register}{r16}} = \code{\htmlClass{register}{r16}/\htmlClass{memory}{m16}} \cdot \code{\htmlClass{constant}{imm8}/\htmlClass{constant}{imm16}/\htmlClass{constant}{imm32}};
imul r32 r32/m32 imm8/imm16/imm32r32=r32/m32imm8/imm16/imm32\code{\htmlClass{register}{r32}} = \code{\htmlClass{register}{r32}/\htmlClass{memory}{m32}} \cdot \code{\htmlClass{constant}{imm8}/\htmlClass{constant}{imm16}/\htmlClass{constant}{imm32}};
imul r64 r64/m64 imm8/imm16/imm32r64=r64/m64imm8/imm16/imm32\code{\htmlClass{register}{r64}} = \code{\htmlClass{register}{r64}/\htmlClass{memory}{m64}} \cdot \code{\htmlClass{constant}{imm8}/\htmlClass{constant}{imm16}/\htmlClass{constant}{imm32}}.

Константа, на которую происходит умножение, не может иметь размер больше 3232 бит. В случае, если операнд-приемник имеет размер 6464 бита, константа будет расширена с сохранением знака до размера 6464 бита.

Деление

Инструкции div и idiv выполняют деление двух операндов. Инструкция div выполняет беззнаковое деление, а инструкция idiv выполняет деление со знаком.

Для обоих инструкций допустим только однооперандный формат.

Однооперандный формат mul/imul source делит регистры dx:ax на операнд source, при этом частное от деления помещается в регистр ax, а остаток от деления помещается в регистр dx.

div/idiv r8/m8ax=alr8/m8\code{\htmlClass{register}{ax}} = \code{\htmlClass{register}{al}} \cdot \code{\htmlClass{register}{r8}/\htmlClass{memory}{m8}};
div/idiv r16/m16ax=dx:ax/r16/m16\code{\htmlClass{register}{ax}} = \code{\htmlClass{register}{dx}:\htmlClass{register}{ax}} / \code{\htmlClass{register}{r16}/\htmlClass{memory}{m16}}, и dx=dx:axmodr16/m16\code{\htmlClass{register}{dx}} = \code{\htmlClass{register}{dx}:\htmlClass{register}{ax}} \bmod \code{\htmlClass{register}{r16}/\htmlClass{memory}{m16}};
div/idiv r32/m32eax=edx:eax/r32/m32\code{\htmlClass{register}{eax}} = \code{\htmlClass{register}{edx}:\htmlClass{register}{eax}} / \code{\htmlClass{register}{r32}/\htmlClass{memory}{m32}}, и edx=edx:eaxmodr32/m32\code{\htmlClass{register}{edx}} = \code{\htmlClass{register}{edx}:\htmlClass{register}{eax}} \bmod \code{\htmlClass{register}{r32}/\htmlClass{memory}{m32}};
div/idiv r64/m64rax=rdx:rax/r64/m64\code{\htmlClass{register}{rax}} = \code{\htmlClass{register}{rdx}:\htmlClass{register}{rax}} / \code{\htmlClass{register}{r64}/\htmlClass{memory}{m64}}, и rdx=rdx:raxmodr64/m64\code{\htmlClass{register}{rdx}} = \code{\htmlClass{register}{rdx}:\htmlClass{register}{rax}} \bmod \code{\htmlClass{register}{r64}/\htmlClass{memory}{m64}}.

Перед выполнением деления нужно подготовить делимое. Для беззнакового деления достаточно просто загрузить делимое в ax и обнулить dx. Для деления со знаком нужно расширить ax со знаком в dx. Расширение можно сделать с помощью соответствующих инструкций cbw, cwd, cwde, cdq, cdqe и cqo.

Расширение

Операции производятся над числами разного размера, поэтому нужно уметь расширять числа до бо´льших размеров.

Инструкция cbw (convert byte to word) превращает байт al в слово ax через расширение со знаком.

Инструкция cwd (convert word to double word) превращает слово ax в двойное слово dx:ax через расширение со знаком.

Инструкция cwde (convert word to double word by extention) превращает слово ax в двойное слово eax через расширение со знаком.

Инструкция cdq (convert double word to quad word) превращает двойное слово eax в четверное слово edx:eax через расширение со знаком.

Инструкция cdqe (convert double word to quad word by extention) превращает двойное слово eax в четверное слово rax через расширение со знаком.

Инструкция cqo (convert quad word to oct word) превращает четверное слово rax в восьмерное слово rdx:rax через расширение со знаком.