Download as pdf or txt
Download as pdf or txt
You are on page 1of 29

8086 Instruction Format:

The 8086 Instruction 8086 Instruction Format vary from 1 to 6 bytes in length.
Fig. 6.8 shows the instruction formats for 1 to 6 bytes instructions. As shown
in the Fig. 6.8, displacements and operands may be either 8-bits or 16-bits
long depending on the instruction. The opcode and the addressing mode is
specified using first two bytes of an instruction.

The opcode/addressing mode byte(s) may be followed by :

• No additional byte
• Two byte EA (For direct addressing only).
• One or two byte displacement
• One or two byte immediate operand
• One or two byte displacement followed by a one or two byte immediate
operand
• Two byte displacement and a two byte segment address (for direct
intersegment addressing only).
Most of the opcodes in 8086 has a special 1-bit indicates. They are :
W-bit : Some instructions of 8086 can operate on byte or a word. The W-bit
in the opcode of such instruction specify whether instruction is a byte
instruction (W = 0) or a word instruction (W = 1).

D-bit : The D-bit in the opcode of the instruction indicates that the register
specified within the instruction is a source register (D = 0) or destination
register (D =1).

S-bit : An 8-bit 2’s complement number can be extended to a 16-bit 2’s


complement number by making all of the bits in the higher-order byte equal
the most significant bit in the low order byte. This is known as sign extension.
The S-bit along with the W-bit indicate :

V-bit : V-bit decides the number of shifts for rotate and shift instructions. If V
= 0, then count = 1; if V = 1, the count is in CL register. For example, if V = 1
and CL = 2 then shift or rotate instruction shifts or rotates 2-bits

Z-bit : It is used for string primitives such as REP for comparison with ZF Flag.
(Refer Appendix A for instruction formats)

As seen from the Fig. 6.8 if an instruction has two opcode/addressing mode
bytes, then the second byte is of one of the following two forms .

where Mod, Reg and R/M fields specify operand as described in the following
tables.
Addressing Modes
Addressing Modes– The term addressing modes refers to the way in which
the operand of an instruction is specified. The addressing mode specifies a
rule for interpreting or modifying the address field of the instruction before the
operand is actually executed.
Addressing modes for 8086 instructions are divided into two
categories:
1) Addressing modes for data
2) Addressing modes for branch
The 8086 memory addressing modes provide flexible access to memory,
allowing you to easily access variables, arrays, records, pointers, and other
complex data types. The key to good assembly language programming is the
proper use of memory addressing modes.
An assembly language program instruction consists of two parts

The memory address of an operand consists of two components:


IMPORTANT TERMS
• Starting address of memory segment.
• Effective address or Offset: An offset is determined by adding any
combination of three address elements: displacement, base and
index.
• Displacement: It is an 8 bit or 16 bit immediate value
given in the instruction.
• Base: Contents of base register, BX or BP.
• Index: Content of index register SI or DI.
According to different ways of specifying an operand by 8086
microprocessor, different addressing modes are used by 8086.
Addressing modes used by 8086 microprocessor are discussed below:
• Implied mode:: In implied addressing the operand is specified in
the instruction itself. In this mode the data is 8 bits or 16 bits long
and data is the part of instruction.Zero address instruction are
designed with implied addressing mode.

Example: CLC (used to reset Carry flag to 0)


• Immediate addressing mode (symbol #):In this mode data is
present in address field of instruction .Designed like one address
instruction format.
Note:Limitation in the immediate mode is that the range of
constants are restricted by size of address field.

Example: MOV AL, 35H (move the data 35H into AL register)
• Register mode: In register addressing the operand is placed in one
of 8 bit or 16 bit general purpose registers. The data is in the
register that is specified by the instruction.
Here one register reference is required to access the data.

Example: MOV AX,CX (move the contents of CX register to AX


register)
• Register Indirect mode: In this addressing the operand’s offset is
placed in any one of the registers BX,BP,SI,DI as specified in the
instruction. The effective address of the data is in the base register
or an index register that is specified by the instruction.
Here two register reference is required to access the data.
The 8086 CPUs let you access memory indirectly through a register
using the register indirect addressing modes.
• MOV AX, [BX](move the contents of memory location s
addressed by the register BX to the register AX)
• Auto Indexed (increment mode): Effective address of the operand
is the contents of a register specified in the instruction. After
accessing the operand, the contents of this register are
automatically incremented to point to the next consecutive memory
location.(R1)+.
Here one register reference,one memory reference and one ALU
operation is required to access the data.
Example:
• Add R1, (R2)+ // OR
• R1 = R1 +M[R2]
R2 = R2 + d
Useful for stepping through arrays in a loop. R2 – start of array d –
size of an element
• Auto indexed ( decrement mode): Effective address of the
operand is the contents of a register specified in the instruction.
Before accessing the operand, the contents of this register are
automatically decremented to point to the previous consecutive
memory location. –(R1)
Here one register reference,one memory reference and one ALU
operation is required to access the data.
Example:
Add R1,-(R2) //OR
R2 = R2-d
R1 = R1 + M[R2]
Auto decrement mode is same as auto increment mode. Both can
also be used to implement a stack as push and pop . Auto
increment and Auto decrement modes are useful for implementing
“Last-In-First-Out” data structures.
• Direct addressing/ Absolute addressing Mode (symbol [ ]): The
operand’s offset is given in the instruction as an 8 bit or 16 bit
displacement element. In this addressing mode the 16 bit effective
address of the data is the part of the instruction.
Here only one memory reference operation is required to access
the data.
Example:ADD AL,[0301] //add the contents of offset
address 0301 to AL
• Indirect addressing Mode (symbol @ or () ):In this mode address
field of instruction contains the address of effective address.Here
two references are required.
1st reference to get effective address.
2nd reference to access the data.
Based on the availability of Effective address, Indirect mode is of
two kind:
1. Register Indirect:In this mode effective address is in the
register, and corresponding register name will be
maintained in the address field of an instruction.
Here one register reference,one memory reference is
required to access the data.
2. Memory Indirect:In this mode effective address is in the
memory, and corresponding memory address will be
maintained in the address field of an instruction.
Here two memory reference is required to access the
data.
• Indexed addressing mode: The operand’s offset is the sum of the
content of an index register SI or DI and an 8 bit or 16 bit
displacement.
Example:MOV AX, [SI +05]
• Based Indexed Addressing: The operand’s offset is sum of the
content of a base register BX or BP and an index register SI or DI.
Example: ADD AX, [BX+SI]
Based on Transfer of control, addressing modes are:
1. PC relative addressing mode: PC relative addressing
mode is used to implement intra segment transfer of
control, In this mode effective address is obtained by
adding displacement to PC.
2. EA= PC + Address field value
PC= PC + Relative value.
3. Base register addressing mode:Base register
addressing mode is used to implement inter segment
transfer of control.In this mode effective address is
obtained by adding base register value to address field
value.
4. EA= Base register + Address field value.
5. PC= Base register + Relative value.
Note:
1. PC relative nad based register both addressing
modes are suitable for program relocation at
runtime.
2. Based register addressing mode is best suitable
to write position independent codes.
Advantages of Addressing Modes
1. To give programmers to facilities such as Pointers,
counters for loop controls, indexing of data and
program relocation.
2.To reduce the number bits in the addressing field of the
Instruction.

Addressing modes in 8086


microprocessor
The way of specifying data to be operated by an instruction is known
as addressing modes. This specifies that the given data is an immediate
data or an address. It also specifies whether the given operand is register or
register pair.
Types of addressing modes:
• Register mode – In this type of addressing mode both the
operands are registers.
Example:
• MOV AX, BX
• XOR AX, DX
ADD AL, BL
• Immediate mode – In this type of addressing mode the source
operand is a 8 bit or 16 bit data. Destination operand can never be
immediate data.
Example:
• MOV AX, 2000
• MOV CL, 0A
• ADD AL, 45
AND AX, 0000
Note that to initialize the value of segment register an register is
required.
MOV AX, 2000
MOV CS, AX
• Displacement or direct mode – In this type of addressing mode
the effective address is directly given in the instruction as
displacement.
Example:
• MOV AX, [DISP]
MOV AX, [0500]
• Register indirect mode – In this addressing mode the effective
address is in SI, DI or BX.
Example:
• MOV AX, [DI]
• ADD AL, [BX]
MOV AX, [SI]
• Based indexed mode – In this the effective address is sum of base
register and index register.
1. Base register: BX, BP
Index register: SI, DI
The physical memory address is calculated according to the base
register.
Example:
MOV AL, [BP+SI]
MOV AX, [BX+DI]
• Indexed mode – In this type of addressing mode the effective
address is sum of index register and displacement.
Example:
• MOV AX, [SI+2000]
MOV AL, [DI+3000]
• Based mode – In this the effective address is the sum of base
register and displacement.
Example:
MOV AL, [BP+ 0100]
• Based indexed displacement mode – In this type of addressing
mode the effective address is the sum of index register, base
register and displacement.
Example:
MOV AL, [SI+BP+2000]
• String mode – This addressing mode is related to string
instructions. In this the value of SI and DI are auto incremented and
decremented depending upon the value of directional flag.
Example:
1. MOVS B
MOVS W
• Input/Output mode – This addressing mode is related with input
output operations.
Example:
• IN A, 45
OUT A, 50
• Relative mode –
In this the effective address is calculated with reference to
instruction pointer.
Example:
• JNZ 8 bit address
IP=IP+8 bit address

Assembler Directives
Definition: Assembler directives are the instructions used by the
assembler at the time of assembling a source program. More specifically,
we can say, assembler directives are the commands or instructions that
control the operation of the assembler.
Assembler directives are the instructions provided to the assembler, not
the processor as the processor has nothing to do with these instructions.
These instructions are also known as pseudo-instructions or pseudo-
opcode.
Now the question arises what assembler directives specifically do?

So, assembler directives:

• show the beginning and end of a program provided to the


assembler,
• used to provide storage locations to data,
• used to give values to variables,
• define the start and end of different segments, procedures or
macros etc. of a program.
What is an Assembler?

We know that assembly language is a less complex and programmer-


friendly language used to program the processors. In assembly language
programming, the instructions are specified in the form of mnemonics
rather in the form of machine code i.e., 0 and 1. But the microprocessor
or microcontrollers are specifically designed in a way that they can only
understand machine language.
Thus assembler is used to convert assembly language into machine code
so that it can be understood and executed by the processor. Therefore, to
control the generation of machine codes from the assembly language,
assembler directives are used. However, machine codes are only generated
for the program that must be provided to the processor and not for
assembler directives because they do not belong to the actual program.
Assembler Directives of 8086
These assembler directives are specifically used by 8086:

ASSUME: Shows the segment name to the assembler


It provides information to the assembler regarding the name of the
program or data segment for that particular segment.

This directive specifies that the instruction of the source program is


stored in logical segment _DONE.

DD: Define Double word


This directive allows the initialization of single or multiple data in the
form of double words (i.e., 4 bytes). The is used to inform the assembler
that the stored data in memory is a double word.

Thus memory stores the given data in the form:


DQ: Define Quad words
It is used to initialise quad words (8-bytes) either one or more than one.
Thereby informing the assembler that the data stored in memory is quad-
word.

DT: Define ten bytes


It is used to allocate and initialize 10 bytes of a variable.

DUP: Duplicate
DUP allows initialization of multiple locations and assigning of values to
them. This allows storing of repeated characters or variables in different
locations.

So this permits the storing of these data in memory and creating 8


identical sets in the memory identified as Book.
DWORD: Double word
This directive is used to indicate that the operand is of double word size.

PROC: Procedure
It defines the starting of a procedure/subroutine.

FAR: This directive is a type specifier that is used by the assembler to


declare intersegment call (i.e., call from different segment).
NEAR: This is used for intrasegment call i.e., a call within the same
segment.
ENDP: End of procedure
This directive shows the termination of a procedure.
SEGMENT: Beginning of a memory segment.
It is used to show the beginning of a memory segment with a specific
name.

ENDS: End of segment


This directive defines the termination of a particular memory segment as
it is specified by its name.

The statements within the segment are nothing but the program code.

EVEN: It is used to inform the assembler to align the data beginning from an
even address.
As data specified with an odd starting address requires 2 byte accessing.
Thus using this directive, data can be aligned with an even starting
address.

PTR: Pointer
This directive shows information regarding the size of the operand.
This shows legal near jump to BX.

PUBLIC: This directive is used to provide a declaration to variables that


are common for different program modules.
STACK: This directive shows the presence of a stack segment.

SHORT: This is used in reference to jump instruction in order to assign a


displacement of one byte.
THIS: It is used along with EQU directive for setting the label to either,
byte, word or double-word.
So, these assembler directives are used by the processors for controlling
the generation of machine code and organization of the program.

Assembly - Logical Instructions


The processor instruction set provides the instructions AND, OR, XOR, TEST, and
NOT Boolean logic, which tests, sets, and clears the bits according to the need of the
program.
The format for these instructions −

Sr.No. Instruction Format

1 AND AND operand1, operand2

2 OR OR operand1, operand2

3 XOR XOR operand1, operand2

4 TEST TEST operand1, operand2

5 NOT NOT operand1

The first operand in all the cases could be either in register or in memory. The second
operand could be either in register/memory or an immediate (constant) value.
However, memory-to-memory operations are not possible. These instructions
compare or match bits of the operands and set the CF, OF, PF, SF and ZF flags.

The AND Instruction


The AND instruction is used for supporting logical expressions by performing bitwise
AND operation. The bitwise AND operation returns 1, if the matching bits from both
the operands are 1, otherwise it returns 0. For example −
Operand1: 0101
Operand2: 0011
----------------------------
After AND -> Operand1: 0001
The AND operation can be used for clearing one or more bits. For example, say the
BL register contains 0011 1010. If you need to clear the high-order bits to zero, you
AND it with 0FH.
AND BL, 0FH ; This sets BL to 0000 1010

Let's take up another example. If you want to check whether a given number is odd
or even, a simple test would be to check the least significant bit of the number. If this
is 1, the number is odd, else the number is even.
Assuming the number is in AL register, we can write −
AND AL, 01H ; ANDing with 0000 0001
JZ EVEN_NUMBER

The following program illustrates this −

Example

Live Demo

section .text
global _start ;must be declared for using gcc

_start: ;tell linker entry point


mov ax, 8h ;getting 8 in the ax
and ax, 1 ;and ax with 1
jz evnn
mov eax, 4 ;system call number (sys_write)
mov ebx, 1 ;file descriptor (stdout)
mov ecx, odd_msg ;message to write
mov edx, len2 ;length of message
int 0x80 ;call kernel
jmp outprog

evnn:

mov ah, 09h


mov eax, 4 ;system call number (sys_write)
mov ebx, 1 ;file descriptor (stdout)
mov ecx, even_msg ;message to write
mov edx, len1 ;length of message
int 0x80 ;call kernel

outprog:
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel

section .data
even_msg db 'Even Number!' ;message showing even number
len1 equ $ - even_msg

odd_msg db 'Odd Number!' ;message showing odd number


len2 equ $ - odd_msg

When the above code is compiled and executed, it produces the following result −
Even Number!
Change the value in the ax register with an odd digit, like −
mov ax, 9h ; getting 9 in the ax

The program would display:


Odd Number!
Similarly to clear the entire register you can AND it with 00H.

The OR Instruction
The OR instruction is used for supporting logical expression by performing bitwise
OR operation. The bitwise OR operator returns 1, if the matching bits from either or
both operands are one. It returns 0, if both the bits are zero.
For example,
Operand1: 0101
Operand2: 0011
----------------------------
After OR -> Operand1: 0111
The OR operation can be used for setting one or more bits. For example, let us
assume the AL register contains 0011 1010, you need to set the four low-order bits,
you can OR it with a value 0000 1111, i.e., FH.
OR BL, 0FH ; This sets BL to 0011 1111

Example
The following example demonstrates the OR instruction. Let us store the value 5 and
3 in the AL and the BL registers, respectively, then the instruction,
OR AL, BL

should store 7 in the AL register −


Live Demo

section .text
global _start ;must be declared for using gcc

_start: ;tell linker entry point


mov al, 5 ;getting 5 in the al
mov bl, 3 ;getting 3 in the bl
or al, bl ;or al and bl registers, result
should be 7
add al, byte '0' ;converting decimal to ascii

mov [result], al
mov eax, 4
mov ebx, 1
mov ecx, result
mov edx, 1
int 0x80

outprog:
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel

section .bss
result resb 1

When the above code is compiled and executed, it produces the following result −
7

The XOR Instruction


The XOR instruction implements the bitwise XOR operation. The XOR operation sets
the resultant bit to 1, if and only if the bits from the operands are different. If the bits
from the operands are same (both 0 or both 1), the resultant bit is cleared to 0.
For example,
Operand1: 0101
Operand2: 0011
----------------------------
After XOR -> Operand1: 0110
XORing an operand with itself changes the operand to 0. This is used to clear a
register.
XOR EAX, EAX

The TEST Instruction


The TEST instruction works same as the AND operation, but unlike AND instruction,
it does not change the first operand. So, if we need to check whether a number in a
register is even or odd, we can also do this using the TEST instruction without
changing the original number.
TEST AL, 01H
JZ EVEN_NUMBER
The NOT Instruction
The NOT instruction implements the bitwise NOT operation. NOT operation reverses
the bits in an operand. The operand could be either in a register or in the memory.
For example,
Operand1: 0101 0011
After NOT -> Operand1: 1010 1100

Assembly - Arithmetic Instructions


The INC Instruction
The INC instruction is used for incrementing an operand by one. It works on a single
operand that can be either in a register or in memory.

Syntax
The INC instruction has the following syntax −
INC destination
The operand destination could be an 8-bit, 16-bit or 32-bit operand.

Example
INC EBX ; Increments 32-bit register
INC DL ; Increments 8-bit register
INC [count] ; Increments the count variable

The DEC Instruction


The DEC instruction is used for decrementing an operand by one. It works on a single
operand that can be either in a register or in memory.

Syntax
The DEC instruction has the following syntax −
DEC destination
The operand destination could be an 8-bit, 16-bit or 32-bit operand.

Example
segment .data
count dw 0
value db 15
segment .text
inc [count]
dec [value]

mov ebx, count


inc word [ebx]

mov esi, value


dec byte [esi]

The ADD and SUB Instructions


The ADD and SUB instructions are used for performing simple addition/subtraction
of binary data in byte, word and doubleword size, i.e., for adding or subtracting 8-bit,
16-bit or 32-bit operands, respectively.

Syntax
The ADD and SUB instructions have the following syntax −
ADD/SUB destination, source
The ADD/SUB instruction can take 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. An ADD or SUB operation sets or clears the overflow
and carry flags.

Example
The following example will ask two digits from the user, store the digits in the EAX
and EBX register, respectively, add the values, store the result in a memory location
'res' and finally display 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

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, [num1]


sub eax, '0'

mov ebx, [num2]


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

When the 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 −
Live Demo

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

When the 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) instruction
handles unsigned data and the IMUL (Integer Multiply) handles signed data. Both
instructions affect the Carry and Overflow flag.

Syntax
The syntax for the MUL/IMUL instructions is as follows −
MUL/IMUL multiplier
Multiplicand in both cases will be in an accumulator, depending upon the size of the
multiplicand and the multiplier and the generated product is also stored in two
registers depending upon the size of the operands. Following section explains MUL
instructions with three different cases −

Sr.No. Scenarios

1
When two bytes are multiplied −
The multiplicand is in the AL register, and the multiplier is a byte in the memory or
in another register. The product is in AX. High-order 8 bits of the product is stored
in AH and the low-order 8 bits are stored in AL.
2
When two one-word values are multiplied −
The multiplicand should be in the AX register, and the multiplier is a word in
memory or another register. For example, for an instruction like MUL DX, you must
store the multiplier in DX and the multiplicand in AX.
The resultant product is a doubleword, which will need two registers. The high-
order (leftmost) portion gets stored in DX and the lower-order (rightmost) portion
gets stored in AX.

3
When two doubleword values are multiplied −
When two doubleword values are multiplied, the multiplicand should be in EAX and
the multiplier is a doubleword value stored in memory or in another register. The
product generated is stored in the EDX:EAX registers, i.e., the high order 32 bits
gets stored in the EDX register and the low order 32-bits are stored in the EAX
register.

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 with 2, and displays the result −
Live Demo

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

When the above code is compiled and executed, it produces the following result −
The result is:
6

The DIV/IDIV Instructions


The division operation generates two elements - a quotient and a remainder. In
case of multiplication, overflow does not occur because double-length registers are
used to keep the product. However, in case of division, overflow may occur. The
processor generates an interrupt if overflow occurs.
The DIV (Divide) instruction is used for unsigned data and the IDIV (Integer Divide)
is used for signed data.

Syntax
The format for the DIV/IDIV instruction −
DIV/IDIV divisor
The dividend is in an accumulator. Both the instructions can work with 8-bit, 16-bit or
32-bit operands. The operation affects all six status flags. Following section explains
three cases of division with different operand size −

Sr.No. Scenarios

1
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.

2
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 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 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 to the EAX register and the 32-bit remainder
goes to the EDX register.
Example
The following example divides 8 with 2. The dividend 8 is stored in the 16-bit AX
register and the divisor 2 is stored in the 8-bit BL register.
Live Demo

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

Assembly - Loops
The JMP instruction can be used for implementing loops. For example, the following
code snippet can be used for executing the loop-body 10 times.
MOV CL, 10
L1:
<LOOP-BODY>
DEC CL
JNZ L1

The processor instruction set, however, includes a group of loop instructions for
implementing iteration. The basic LOOP instruction has the following syntax −
LOOP label
Where, label is the target label that identifies the target instruction as in the jump
instructions. The LOOP instruction assumes that the ECX register contains the
loop count. When the loop instruction is executed, the ECX register is decremented
and the control jumps to the target label, until the ECX register value, i.e., the counter
reaches the value zero.
The above code snippet could be written as −
mov ECX,10
l1:
<loop body>
loop l1

Example
The following program prints the number 1 to 9 on the screen −
Live Demo

section .text
global _start ;must be declared for using gcc

_start: ;tell linker entry point


mov ecx,10
mov eax, '1'

l1:
mov [num], eax
mov eax, 4
mov ebx, 1
push ecx

mov ecx, num


mov edx, 1
int 0x80

mov eax, [num]


sub eax, '0'
inc eax
add eax, '0'
pop ecx
loop l1

mov eax,1 ;system call number (sys_exit)


int 0x80 ;call kernel
section .bss
num resb 1

When the above code is compiled and executed, it produces the following result −
123456789:

You might also like