2. The ADD/SUB instructioncantake place between:
Register to register
Memory to register
Register to memory
Register to constant data
Memory to constant data
However, like other instructions, memory-to-memory operations are not possible using ADD/SUB instructions.
AnADD or SUB operationsets or clears the overflow and carry flags.
Example:
The following example asks two digits fromthe user, stores the digits inthe EAX and EBX register,
respectively, adds the values, stores the result ina memory location'res' and finally displays the result.
SYS_EXIT equ 1
SYS_READ equ 3
SYS_WRITE equ 4
STDIN equ 0
STDOUT equ 1
segment .data
msg1 db "Enter a digit ", 0xA,0xD
len1 equ $- msg1
msg2 db "Please enter a second digit", 0xA,0xD
len2 equ $- msg2
msg3 db "The sum is: "
len3 equ $- msg3
segment .bss
num1 resb 2
num2 resb 2
res resb 1
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg1
mov edx, len1
int 0x80
mov eax, SYS_READ
mov ebx, STDIN
mov ecx, num1
mov edx, 2
int 0x80
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg2
mov edx, len2
int 0x80
mov eax, SYS_READ
mov ebx, STDIN
mov ecx, num2
mov edx, 2
int 0x80
3. mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg3
mov edx, len3
int 0x80
; moving the first number to eax register and second number to ebx
; and subtracting ascii '0' to convert it into a decimal number
mov eax, [number1]
sub eax, '0'
mov ebx, [number2]
sub ebx, '0'
; add eax and ebx
add eax, ebx
; add '0' to to convert the sum from decimal to ASCII
add eax, '0'
; storing the sum in memory location res
mov [res], eax
; print the sum
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, res
mov edx, 1
int 0x80
exit:
mov eax, SYS_EXIT
xor ebx, ebx
int 0x80
Whenthe above code is compiled and executed, it produces the following result:
Enter a digit:
3
Please enter a second digit:
4
The sum is:
7
The program with hardcoded variables:
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov eax,'3'
sub eax, '0'
mov ebx, '4'
sub ebx, '0'
add eax, ebx
add eax, '0'
mov [sum], eax
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,sum
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 sum is:", 0xA,0xD
len equ $ - msg
segment .bss
sum resb 1
4. Whenthe above code is compiled and executed, it produces the following result:
The sum is:
7
The MUL/IMUL Instruction
There are two instructions for multiplying binary data. The MUL (Multiply) instructionhandles unsigned data and
the IMUL (Integer Multiply) handles signed data. Bothinstructions affect the Carry and Overflow flag.
Syntax:
The syntax for the MUL/IMUL instructions is as follows:
MUL/IMUL multiplier
Multiplicand inbothcases willbe inanaccumulator, depending uponthe size of the multiplicand and the multiplier
and the generated product is also stored intwo registers depending uponthe size of the operands. Following
sectionexplains MUL instructions withthree different cases:
SN Scenarios
1 When two bytes are multiplied
The multiplicand is inthe AL register, and the multiplier is a byte inthe memory or inanother register.
The product is inAX. High-order 8 bits of the product is stored inAH and the low-order 8 bits are
stored inAL
2 When two one-word values are multiplied
The multiplicand should be inthe AX register, and the multiplier is a word inmemory or another
register. For example, for aninstructionlike MUL DX, youmust store the multiplier inDX and the
multiplicand inAX.
The resultant product is a doubleword, whichwillneed two registers. The high-order (leftmost)
portiongets stored inDX and the lower-order (rightmost) portiongets stored inAX.
3 When two doubleword values are multiplied
Whentwo doubleword values are multiplied, the multiplicand should be inEAX and the multiplier is a
doubleword value stored inmemory or inanother register. The product generated is stored inthe
EDX:EAX registers, i.e., the highorder 32 bits gets stored inthe EDX register and the low order 32-
bits are stored inthe EAX register.
5. Example:
MOV AL, 10
MOV DL, 25
MUL DL
...
MOV DL, 0FFH ; DL= -1
MOV AL, 0BEH ; AL = -66
IMUL DL
Example:
The following example multiplies 3 with2, and displays the result:
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov al,'3'
sub al, '0'
mov bl, '2'
sub bl, '0'
mul bl
add al, '0'
mov [res], al
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
Whenthe above code is compiled and executed, it produces the following result:
The result is:
6
The DIV/IDIV Instructions
The divisionoperationgenerates two elements - a quotient and a remainder. Incase of multiplication,
overflow does not occur because double-lengthregisters are used to keep the product. However, incase of
division, overflow may occur. The processor generates aninterrupt if overflow occurs.
The DIV (Divide) instructionis used or unsigned data and the IDIV (Integer Divide) is used or signed data.
Syntax:
The format for the DIV/IDIV instruction:
DIV/IDIV divisor
The dividend is inanaccumulator. Boththe instructions canwork with8-bit, 16-bit or 32-bit operands. The
operationaffects allsix status flags. Following sectionexplains three cases of divisionwithdifferent operand
6. size:
SN Scenarios
1 When the divisor is 1 byte
The dividend is assumed to be inthe AX register (16 bits). After division, the quotient goes to the AL
register and the remainder goes to the AH register.
2 When the divisor is 1 word
The dividend is assumed to be 32 bits long and inthe DX:AX registers. The high-order 16 bits are in
DX and the low-order 16 bits are inAX. After division, the 16-bit quotient goes to the AX register and
the 16-bit remainder goes to the DX register.
3 When the divisor is doubleword
The dividend is assumed to be 64 bits long and inthe EDX:EAX registers. The high-order 32 bits are
inEDX and the low-order 32 bits are inEAX. After division, the 32-bit quotient goes to the EAX
register and the 32-bit remainder goes to the EDX register.
Example:
The following example divides 8 with2. The dividend 8 is stored inthe 16-bit AX register and the divisor
2 is stored inthe 8-bit BL register.
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov ax,'8'
7. 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
Whenthe above code is compiled and executed, it produces the following result:
The result is:
4