Arithmetic instructions - In assembly language, arithmetic operations or arithmetic instructions are used to perform mathematical operations like addition, subtraction, multiplication, division, etc.
NASM - INC DEC ADD and SUB MUL/IMUL DIV/IDIV
Arithmetic Instructions - INC DEC ADD and SUB MUL/IMUL DIV/IDIV In NASM assembly language, these (INC, DEC, ADD, SUB, MUL/IMUL, DIV/IDIV) instructions are used in the same way as the arithmetic operators (++, --, +, -, ×, ÷).
INC Instruction
INC instruction is used to increment (++) an operand by one. It operates on a single operand which can be either in a register or in memory.
Syntax - INC destination
INC EBX ; Increments 32-bit register
INC DL ; Increments 8-bit register
INC [count] ; Increments the count variable
The operand destination can be an 8-bit, 16-bit, or 32-bit operand.
DEC Instructions
DEC Instructions - The DEC instruction is used to decrement an operand by one (--). It operates on a single operand which can be either in a register or in memory.
Syntax - DEC destination
DEC EBX ; Increments 32-bit register
DEC DL ; Increments 8-bit register
DEC [count] ; Increments the count variable
The operand destination can be an 8-bit, 16-bit, or 32-bit operand.
ADD and SUB instructions
ADD and SUB instructions are used to perform simple addition/subtraction of binary data in byte, word and doubleword sizes,
add eax, ebx
add eax, '0'
sub ebx, '0'
sub eax, '7 '
sub eax, ebx
ADD/SUB instructions - may apply to
- Register to register
- Memory to register
- Register to memory
- Register to constant data
- Memory to constant data
Like other instructions, memory-to-memory operations are not possible using the ADD/SUB instructions. An ADD or SUB operation sets or clears the overflow and carry flags.
The MUL/IMUL Instruction
There are two instructions for multiplying binary data. The MUL (Multiply) instruction handles unsigned data and the IMUL (Integer Multiply) handles signed data. Both instructions affect the carry and overflow flags..
Syntax - MUL/IMUL multiplier
In both cases the multiplier will be in an accumulator, depending on the size of the multiplier and the multiplier and the product generated is stored in two registers depending on the size of the operand.
The following section explains the MUL instructions with three different cases −
- When multiplying two bytes - the multiplier is in the AL register, and the multiplier is a byte in memory or in another register. The product is in AX. The high order 8 bits of the product are stored in AH and the low order 8 bits are stored in AL.
AL × 8 bit source = AH AL - When two one-word values are multiplied - When two one-word values are multiplied - the result is stored in AX and DX.
AX × 16 bit source = DX AX - When multiplying two doubleword values - When two doubleword values are multiplied, the multiplier must be in EAX. The product is stored in the EDX:EX registers, that is, the high-order 32-bits are stored in the EDX register and the low-order 32-bits are stored in the EAX register.
EAX × 32 bit source = EDX EAX
Exampal
MOV AL, 10
MOV DL, 25
MUL DL
...
MOV DL, 0FFH ; DL= -1
MOV AL, 0BEH ; AL = -66
IMUL DL
DIV/IDIV instruction
The DIV (Divide) instruction is used for unsigned data and IDIV (Integer Divide) is used for signed data.
The division operation produces two elements – a quotient and a remainder. In the case of multiplication, overflow does not occur because double-length registers are used to hold the product. However, overflow can occur in case of division. If overflow occurs, the processor generates an interrupt.
Syntax - DIV/IDIV divisor
is in the dividend accumulator. Both instructions can work with 8-bit, 16-bit or 32-bit operands. The operation affects all six status flags.
The following section explains the three cases of division with different operand sizes −
- When the divisor is 1 byte -the dividend is assumed to be in the AX register (16 bits). After division the quotient goes to the AL register and the remainder goes to the AH register.
16 bit divident
AX
8 bit divisor
=Quoitient
AL
AndRemainde
AH
- When the divisor is 1 word - the dividend is assumed to be 32 bits long and in the DX:AX registers. The high-order 16 bits are in DX and the low-order 16 bits are in AX. After division, the 16-bit quotient goes into the AX register and the 16-bit remainder goes into the DX register.
32 bit divident
DXAX
16 bit divisor
=Quoitient
AX
AndRemainde
DX
- When the denominator is a double word - The dividend is assumed to be 64 bits long and in the EDX:EAX registers. The high order 32 bits are in EDX and the low order 32 bits are in EAX. After division, the 32-bit quotient goes into the EAX register and the 32-bit remainder goes into the EDX register.
64 bit divident
EDXEAX
16 bit divisor
=Quoitient
EAX
AndRemainde
EDX
Exampal
In the following example you can see the assembly arithmetic operations and instructions.
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov ax,'8'
sub ax, '0'
mov bl, '2'
sub bl, '0'
div bl
add ax, '0'
mov [res], ax
mov ecx,msg
mov edx, len
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov ecx,res
mov edx, 1
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data
msg db "The result is:", 0xA,0xD
len equ $- msg
segment .bss
res resb 1
When the above code is compiled and executed, it produces the following result −
The result is: 4