X86 Assembly/Arithmetic
< X86 AssemblyArithmetic instructions
Arithmetic instructions take two operands: a destination and a source. The destination must be a register or a memory location. The source may be either a memory location, a register, or a constant value. Note that at least one of the two must be a register, because operations may not use a memory location as both a source and a destination.
add src, dest | GAS Syntax |
add dest, src | Intel syntax |
This adds src
to dest
. If you are using the MASM syntax, then the result is stored in the first argument, if you are using the GAS syntax, it is stored in the second argument.
sub src, dest | GAS Syntax |
sub dest, src | Intel syntax |
Like ADD, only it subtracts source from destination instead. In C: dest -= src;
mul arg
This multiplies "arg" by the value of corresponding byte-length in the AX register.
operand size 1 byte 2 bytes 4 bytes other operand AL AX EAX higher part of result stored in: AH DX EDX lower part of result stored in: AL AX EAX
In the second case, the target is not EAX for backward compatibility with code written for older processors.
imul arg
As MUL, only signed. The IMUL instruction has the same format as MUL, but also accepts two other formats like so:
imul src, dest | GAS Syntax |
imul dest, src | Intel syntax |
This multiplies src
by dest
. If you are using the NASM syntax, then the result is stored in the first argument, if you are using the GAS syntax, it is stored in the second argument.
imul aux, src, dest | GAS Syntax |
imul dest, src, aux | Intel syntax |
This multiplies src
by aux
and places it into dest
. If you are using the NASM syntax, then the result is stored in the first argument, if you are using the GAS syntax, it is stored in the third argument.
div arg
This divides the value in the dividend register(s) by "arg", see table below.
divisor size 1 byte 2 bytes 4 bytes dividend AX DX:AX EDX:EAX remainder stored in: AH DX EDX quotient stored in: AL AX EAX
The colon (:) means concatenation. With divisor size 4, this means that EDX are the bits 32-63 and EAX are bits 0-31 of the input number (with lower bit numbers being less significant, in this example).
As you typically have 32-bit input values for division, you often need to use CDQ to sign-extend EAX into EDX just before the division.
If quotient does not fit into quotient register, arithmetic overflow interrupt occurs. All flags are in undefined state after the operation.
idiv arg
As DIV, only signed.
neg arg
Arithmetically negates the argument (i.e. two's complement negation).
Carry Arithmetic Instructions
adc src, dest | GAS Syntax |
adc dest, src | Intel syntax |
Add with carry. Adds src
+ carry flag
to dest
, storing result in dest
. Usually follows a normal add instruction to deal with values twice as large as the size of the register. In the following example, source contains a 64-bit number which will be added to destination.
mov eax, [source] ; read low 32 bits
mov edx, [source+4] ; read high 32 bits
add [destination], eax ; add low 32 bits
adc [destination+4], edx ; add high 32 bits, plus carry
sbb src, dest | GAS Syntax |
sbb dest, src | Intel syntax |
Subtract with borrow. Subtracts src
+ carry flag
from dest
, storing result in dest
. Usually follows a normal sub instruction to deal with values twice as large as the size of the register.
Increment and Decrement
inc arg
Increments the register value in the argument by 1. Performs much faster than ADD arg, 1.
dec arg
Decrements the register value in the argument by 1. Performs much faster than SUB arg, 1.
Pointer arithmetic
The lea
instruction can be used for arithmetic, especially on pointers. See X86 Assembly/Data Transfer#Load Effective Address.