Lab Manual
Lab Manual
Lab Manual
5. Registers
6. Addressing Modes
Arithmetic Instructions
7.
8. Arithmetic Instructions
9. Conditional Statement
Loops
10.
11 Arrays
Procedures
12
Installation Process:
Click "Download for PC" button. This opens a new tab and the downloading starts.
The Emu8086 icon will appear on your desktop. You can use it whenever you want. Hence,
today we learnt about Emu8086. We saw the brief introduction along will the installation
process in detail.
PRACTICAL NO: 2
Basic Assembly
Introduction:
What is Assembly language?
Every PC has a microprocessor that manages the computer arithmetical, logical and control
activities.
Each family of processor has its own set of instructions for handling various operations like
getting input from the keyboard, displaying information on the screen and performing various
jobs.
These set of instructions are called ‘machine language instructions’.
Syntax:
.Model is a directive that specifies the memory configuration for the assembly language
Memory model that can be used in assembly are as follows:
Tiny model:
The model uses maximum of 64K bytes for code and data.
Small model:
The model uses maximum of 64K bytes for data (Code <=64K and Data<=64K).
This model is most widely used memory model and is sufficient for all the programs to
be used for practice.
Medium Model:
This model uses maximum of 64K bytes for Data and Code can exceed 64K bytes
(Code>64K and Data<=64K)
Compact model:
This model uses maximum of 64K bytes for Code and Data can exceed 64K bytes.
(Code<=64K and Data>64K)
Large model:
Both Code and Data can exceed 64K bytes. However, no single dataset can exceed 64K
bytes (Code>64K and Data>64K).
Huge model:
Both Code and Data can exceed 64K bytes. Additionally, a single dataset can exceed
64K bytes (Code>64K and Data>64K).
Flat model:
Window NT application
PROGRAM:
Print a character on screen using assembly language
Solution:
.model small #determine the data size code or program, code data store,
.stack 100h #small level data quote, a block of memory to store stack, memory define for
hexadecimal
.data #All variable definition, initialization
;variables are defined here
.code # program instruct to tell cpu what to do
Main proc #inside a code segment, instructions are organized as procedures.
Mov dl, ‘A’
Mov ah,2
Int 21h
Three lines 1 charater print on console. Source O2 move towards ah destination, ah tell cpu you
have to perform out put.
Ineterupt call to call 21h, cpu went to ah, ask for instruction and get 02 to perform output then
will move to dl to get ‘a’
Mov ah,4ch 4ch move to ah, control return of id where youre working, after printing show
it returns id
Int 21h interrupt call,
Main endp
End main code sequence end
OUTPUT:
PRACTICAL NO 3
Data Conversion Binary to Hexadecimal
Introduction:
Binary is the simplest kind of number system that uses only two digits of 0 and 1 (i.e. value of
base 2). Since digital electronics have only these two states (either 0 or 1), so binary number is
most preferred in modern computer engineer, networking and communication specialists, and
other professionals.
Whereas Hexadecimal number is one of the number systems which has value is 16 and it has
only 16 symbols − 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 and A, B, C, D, E, F. Where A, B, C, D, E and F are
single bit representations of decimal value 10, 11, 12, 13, 14 and 15 respectively.
Hexadecimal number system provides convenient way of converting large binary numbers into
more compact and smaller groups. There are various ways to convert a binary number into
hexadecimal number. You can convert using direct methods or indirect methods. First, you need
to convert a binary into other base system (e.g., into decimal, or into octal). Then you need to
convert it hexadecimal number.
Since number numbers are type of positional number system. That means weight of the positions
from right to left are as 160, 161, 162, 163and so on… for the integer part and weight of the
positions from left to right are as 16-1, 16-2, 16-3and so on… for the fractional part.
Using Grouping
Since, there are only 16 digits (from 0 to 7 and A to F) in hexadecimal number system, so we can
represent any digit of hexadecimal number system using only 4 bit as following below.
So, if you make each group of 4 bit of binary input number, then replace each group of binary
number from its equivalent hexadecimal digits. That will be hexadecimal number of given
number. Note that you can add any number of 0’s in leftmost bit (or in most significant bit) for
integer part and add any number of 0’s in rightmost bit (or in least significant bit) for fraction
part for completing the group of 4 bit, this does not change value of input binary number.
So, these are following steps to convert a binary number into hexadecimal number.
Take binary number
Divide the binary digits into groups of four (starting from right) for integer part and start
from left for fraction part.
Convert each group of four binary digits to one hexadecimal digit.
This is simple algorithm where you have to grouped binary number and replace their equivalent
hexadecimal digit.
Example –
Convert binary number 1010101101001 into hexadecimal number.
Since there is no binary point here and no fractional part.
So, Binary to hexadecimal is,
= (1010101101001)2
= (1 0101 0110 1001)2
= (0001 0101 0110 1001)2
= (1 5 6 9)16
= (1569)16
PRACTICAL NO 4
Assembly directives
PROGRAM:
To write a Program in assembly print a name on screen
.Model small
.stack 100h
.data
.code
main proc
mov dl, ‘a’
mov ah,2
int 21h
mov dl, ‘l’
mov ah,2
int 21h
mov ah,4ch
int 21h
main endp
end main
OUTPUT;
Program: To write a program in assemble take input from user and display on screen
Solution:
.model small
.stack 100h
.data
.code
main proc
mov ah,1
int 21h
mov dl, al
mov ah, 2
int 21h
mov ah,4ch
int 21h
main endp
end main
OUTPUT:
Practical No 5
AIM:
DX:AX concatenated into 32-bit register for some MUL and DIV operations
Specifying ports in some IN and OUT operations
7) BP - base pointer:
Primarily used to access parameters passed via the stack
Offset address relative to SS
8) SP - stack pointer:
Always points to top item on the stack
Offset address relative to SS
Always points to word (byte at even address)
An empty stack will had SP = FFFEh
Segment Registers
Flag Register
The FLAGS register is the status register in Intel x86 microprocessors that contains the current
state of the processor. This register is 16 bits wide. Its successors, the EFLAGS and
RFLAGS registers, are 32 bits and 64 bits wide, respectively.
1. Carry Flag (CF) - this flag is set to 1 when there is an unsigned overflow. For example
when you add bytes 255 + 1(result is not in range 0...255). When there is no overflow this
flag is set to 0.
2. Parity Flag (PF) - this flag is set to 1 when there is even number of one bits in result,
and to 0 when there is odd number of one bits. Even if result is a word only 8 low bits are
analyzed.
3. Auxiliary Flag (AF) - set to 1 when there is an unsigned overflow for low nibble (4
bits).
4. Zero Flag (ZF) - set to 1 when result is zero. For none zero result this flag is set to 0.
5. Sign Flag (SF) - set to 1 when result is negative. When result is positive it is set to 0.
Actually this flag take the value of the most significant bit.
6. Trap Flag (TF) - Used for on-chip debugging.
7. Interrupt enable Flag (IF) - when this flag is set to 1 CPU reacts to interrupts from
external devices.
8. Direction Flag (DF) - this flag is used by some instructions to process data chains, when
this flag is set to 0 - the processing is done forward, when this flag is set to 1 the
processing is done backward.
9. Overflow Flag (OF) - set to 1 when there is a signed overflow.
Program:
Practical No 6
Addressing Modes
Introduction:
Register Addressing
In this addressing mode, a register contains the operand. Depending upon the instruction, the
register may be the first operand, the second operand or both.
For example,
MOV DX, TAX_RATE ; Register in first operand
MOV COUNT, CX ; Register in second operand
MOV EAX, EBX ; Both the operands are in registers
As processing data between registers does not involve memory, it provides fastest processing of
data.
Immediate Addressing
An immediate operand has a constant value or an expression. When an instruction with two
operands uses immediate addressing, the first operand may be a register or memory location, and
the second operand is an immediate constant. The first operand defines the length of the data.
For example,
BYTE_VALUE DB 150 ; A byte value is defined
WORD_VALUE DW 300 ; A word value is defined
ADD BYTE_VALUE, 65 ; An immediate operand 65 is added
MOV AX, 45H ; Immediate constant 45H is transferred to AX
Direct Memory Addressing
When operands are specified in memory addressing mode, direct access to main memory,
usually to the data segment, is required. This way of addressing results in slower processing of
data. To locate the exact location of data in memory, we need the segment start address, which is
typically found in the DS register and an offset value. This offset value is also called effective
address.
In direct addressing mode, the offset value is specified directly as part of the instruction, usually
indicated by the variable name. The assembler calculates the offset value and maintains a symbol
table, which stores the offset values of all the variables used in the program.
In direct memory addressing, one of the operands refers to a memory location and the other
operand references a register.
For example,
ADD BYTE_VALUE, DL ; Adds the register in the memory location
MOV BX, WORD_VALUE ; Operand from the memory is added to register
MOV instruction
The MOV instruction is the most important command in the 8086 because it moves data from
one location to another. It also has the widest variety of parameters; so it the assembler
programmer can use MOV effectively, the rest of the commands are easier to understand.
Format:
MOV destination, source
The possible combinations of operands are as follows :
MOV copies the data in the source to the destination. The data can be either a byte or a word.
Sometimes this has to be explicitly stated when the assembler cannot determine from the
operands whether a byte or word is being referenced.
PROGRAM:
Program to convert Capital letter to small in assembly
Code:
.model small
.stack 100h
.data
.code
main proc
mov ah,1
int 21h
mov dl, al
add dl,32
int 21h
mov ah,2
int 21h
mov ah,4ch
int 21h
main endp
end main
Output:
Practical NO 7
Arithmetic Instructions
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 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.
Aim: Program to print capital letters from A to Z using loop in assembly language
Program:
.model small
.stack 100h
.data
.code
main proc
mov cx, 26
mov dx, 65
l1:
mov ah,2
int 21h
inc dx
loop l1
mov ah,4ch
int 21h
main endp
end main
OUTPUT:
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.
PROGRAM:
; Program to input two numbers and add them in assembly language
.model small
.stack 100h
.data
.code
main proc
mov ah,1
int 21h
mov bl, al
mov al,1
int 21h
add bl, al
sub bl, 48
mov dl, bl
mov ah,2
int 21h
mov ah,4ch
int 21h
main endp
end main
OUTPUT:
PROGRAM:
Program to subtract two numbers in assembly language
Solution:
.model small
.stack 100h
.data
.code
main proc
mov bl,3
mov cl,1
sub bl,cl
add bl,48
mov dl,bl
mov ah,2
int 21h
mov ah,4ch
int 21h
main endp
end main
OUTPUT:
PROGRAM:
Program to add two numbers
Solution:
.model small
.stack 100h
.data
.code
main proc
mov bl,1
mov cl,2
add bl,cl
add bl,48
mov dl,bl
mov ah,2
int 21h
mov ah,4ch
int 21h
main endp
end main
OUTPUT:
Practical No 8
Arithmetic Instructions
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
.
Sr.No Scenarios
.
1 Unconditional jump
This is performed by the JMP instruction. Conditional execution often
involves a transfer of control to the address of an instruction that does not
follow the currently executing instruction. Transfer of control may be
forward, to execute a new set of instructions or backward, to re-execute the
same steps.
2 Conditional jump
This is performed by a set of jump instructions j<condition> depending upon
the condition. The conditional instructions transfer the control by breaking the
sequential flow and they do it by changing the offset value in IP.
CMP Instruction
The CMP instruction compares two operands. It is generally used in conditional execution. This
instruction basically subtracts one operand from the other for comparing whether the operands
are equal or not. It does not disturb the destination or source operands. It is used along with the
conditional jump instruction for decision making.
Syntax
CMP destination, source
CMP compares two numeric data fields. The destination operand could be either in register or in
memory. The source operand could be a constant (immediate) data, register or memory.
Example
CMP DX, 00 ; Compare the DX value with zero
JE L7 ; If yes, then jump to label L7
.
.
L7: ...
CMP is often used for comparing whether a counter value has reached the number of times a
loop needs to be run. Consider the following typical condition −
INC EDX
CMP EDX, 10 ; Compares whether the counter has reached 10
JLE LP1 ; If it is less than or equal to 10, then jump to LP1
Unconditional Jump
As mentioned earlier, this is performed by the JMP instruction. Conditional execution often
involves a transfer of control to the address of an instruction that does not follow the currently
executing instruction. Transfer of control may be forward, to execute a new set of instructions or
backward, to re-execute the same steps.
Syntax
The JMP instruction provides a label name where the flow of control is transferred immediately.
The syntax of the JMP instruction is −
JMP label
Example
The following code snippet illustrates the JMP instruction −
MOV AX, 00 ; Initializing AX to 0
MOV BX, 00 ; Initializing BX to 0
MOV CX, 01 ; Initializing CX to 1
L20:
ADD AX, 01 ; Increment AX
ADD BX, AX ; Add AX to BX
SHL CX, 1 ; shift left CX, this in turn doubles the CX value
JMP L20 ; repeats the statements
Conditional Jump
If some specified condition is satisfied in conditional jump, the control flow is transferred to a
target instruction. There are numerous conditional jump instructions depending upon the
condition and data.
Following are the conditional jump instructions used on signed data used for arithmetic
operations −
Aim: Program to print the input number is equal or not in assembly language
PROGRAM:
.model small
.stack 100h
.data
msg1 db 'number is equal$'
msg2 db 'number is not equal$'
.code
main proc
mov ax, @data
mov ds,ax
mov dl, '3'
mov ah,1
int 21h
cmp al,dl
je l1
mov dx,offset msg2
mov ah,9
int 21h
l1:
mov dx, offset msg1
mov ah,9
int 21h
mov ah, 4ch
int 21h
main endp
end main
OUTPUT:
Practical No 10
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
Solution:
.model small
.stack 100h
.data
.code
main proc
mov cx, 10
mov dx,48
l1:
mov ah,2
int 21h
add dx,1
loop l1
mov ah,4ch
int 21h
main endp
end main
OUTPUT:
Practical No 11
Arrays
We have already discussed that the data definition directives to the assembler are used for
allocating storage for variables. The variable could also be initialized with some specific value.
The initialized value could be specified in hexadecimal, decimal or binary form.
For example, we can define a word variable 'months' in either of the following way −
MONTHS DW 12
MONTHS DW 0CH
MONTHS DW 0110B
The data definition directives can also be used for defining a one-dimensional array. Let us
define a one-dimensional array of numbers.
NUMBERS DW 34, 45, 56, 67, 75, 89
The above definition declares an array of six words each initialized with the numbers 34, 45, 56,
67, 75, 89. This allocates 2x6 = 12 bytes of consecutive memory space. The symbolic address of
the first number will be NUMBERS and that of the second number will be NUMBERS + 2 and
so on.
Let us take up another example. You can define an array named inventory of size 8, and initialize
all the values with zero, as −
INVENTORY DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
DW 0
Which can be abbreviated as –
INVENTORY DW 0, 0 , 0 , 0 , 0 , 0 , 0 , 0
The TIMES directive can also be used for multiple initializations to the same value. Using
TIMES, the INVENTORY array can be defined as:
INVENTORY TIMES 8 DW 0
Program to print an array using loop in assembly language programming
PROGRAM:
.model small
.stack 100h
.data
array db 'a','b','c'
.code
main proc
mov ax, @data
mov ds,ax
mov si,offset array
mov cx,3
l1:
mov dx, [si]
mov ah,2
int 21h
loop l1
mov ah, 4ch
int 21h
main endp
end main
OUTPUT:
Practical No 12
Procedures
Procedures or subroutines are very important in assembly language, as the assembly language
programs tend to be large in size. Procedures are identified by a name. Following this name, the
body of the procedure is described which performs a well-defined job. End of the procedure is
indicated by a return statement.
Syntax
PROGRAM:
.model small
.stack 100h
.data
var1 db 100 dup('$')
.code
main proc
mov ax, @data
mov ds,ax
mov si,offset var1
l1:
mov ah,1
int 21h
cmp al,13
je programend
mov [si],al
inc si
jmp l1
programend:
mov dx, offset var1
mov ah,9
int 21h
loop l1
mov ah, 4ch
int 21h
main endp
end main
Output:
Practical No 13
Stacks Data Structure
A stack is an array-like data structure in the memory in which data can be stored and removed
from a location called the 'top' of the stack. The data that needs to be stored is 'pushed' into the
stack and data to be retrieved is 'popped' out from the stack. Stack is a LIFO data structure, i.e.,
the data stored first is retrieved last.
Assembly language provides two instructions for stack operations: PUSH and POP. These
instructions have syntaxes like −
PUSH operand
POP address/register
The memory space reserved in the stack segment is used for implementing stack. The registers
SS and ESP (or SP) are used for implementing the stack. The top of the stack, which points to
the last data item inserted into the stack is pointed to by the SS:ESP register, where the SS
register points to the beginning of the stack segment and the SP (or ESP) gives the offset into the
stack segment.
The stack implementation has the following characteristics −
Only words or doublewords could be saved into the stack, not a byte.
The stack grows in the reverse direction, i.e., toward the lower memory address
The top of the stack points to the last item inserted in the stack; it points to the lower byte
of the last word inserted.
As we discussed about storing the values of the registers in the stack before using them for some
use; it can be done in following way −
; Save the AX and BX registers in the stack
PUSH AX
PUSH BX
pop ax
pop bx
mov dx,ax
mov ah,2
int 21h
mov dx, bx
mov ah,2
int 21h
main endp
end main
OUTPUT:
Program:
.model small
.stack 100h
.data
var1 db 100 dup('$')
.code
main proc
mov ax,2
push ax
pop ax
mov dx,ax
mov ah,2
int 21h
mov ah, 4ch
int 21h
main endp
end main
OUTPUT:
Practical No 14
Recursion
A recursive procedure is one that calls itself. There are two kind of recursion: direct and indirect.
In direct recursion, the procedure calls itself and in indirect recursion, the first procedure calls a
second procedure, which in turn calls the first procedure.
Recursion could be observed in numerous mathematical algorithms. For example, consider the
case of calculating the factorial of a number. Factorial of a number is given by the equation −
Fact (n) = n * fact (n-1) for n > 0
For example: factorial of 5 is 1 x 2 x 3 x 4 x 5 = 5 x factorial of 4 and this can be a good example
of showing a recursive procedure. Every recursive algorithm must have an ending condition, i.e.,
the recursive calling of the program should be stopped when a condition is fulfilled. In the case
of factorial algorithm, the end condition is reached when n is 0.
Practical No 15
Macros
Writing a macro is another way of ensuring modular programming in assembly language.
A macro is a sequence of instructions, assigned by a name and could be used anywhere in
the program.
In NASM, macros are defined with %macro and %endmacro directives.
The macro begins with the %macro directive and ends with the %endmacro directive.
The Syntax for macro definition −
%macro macro_name number_of_params
<macro body>
%endmacro
Where, number_of_params specifies the number parameters, macro_name specifies the name of
the macro.
The macro is invoked by using the macro name along with the necessary parameters. When you
need to use some sequence of instructions many times in a program, you can put those
instructions in a macro and use it instead of writing the instructions all the time.
For example, a very common need for programs is to write a string of characters in the screen.
For displaying a string of characters, you need the following sequence of instructions −
mov edx,len ;message length
mov ecx,msg ;message to write
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
In the above example of displaying a character string, the registers EAX, EBX, ECX and EDX
have been used by the INT 80H function call. So, each time you need to display on screen, you
need to save these registers on the stack, invoke INT 80H and then restore the original value of
the registers from the stack. So, it could be useful to write two macros for saving and restoring
data.
We have observed that, some instructions like IMUL, IDIV, INT, etc., need some of the
information to be stored in some particular registers and even return values in some specific
register(s). If the program was already using those registers for keeping important data, then the
existing data from these registers should be saved in the stack and restored after the instruction is
executed.
print str2
mov ah, 4ch
int 21h
main endp
spacekey proc
mov dx,10
mov ah,2
int 21h
mov dx,13
mov ah,2
int 21h
ret
spacekey endp
end main
Practical No 16
Strings
We have already used variable length strings in our previous examples. The variable length
strings can have as many characters as required. Generally, we specify the length of the string by
either of the two ways −
$ points to the byte after the last character of the string variable msg. Therefore, $-msg gives the
length of the string. We can also write
msg db 'Hello, world!',0xa ;our dear string
len equ 13 ;length of our dear string
Alternatively, you can store strings with a trailing sentinel character to delimit a string instead of
storing the string length explicitly. The sentinel character should be a special character that does
not appear within a string.
For example −
message DB 'I am loving it!', 0
String Instructions
Each string instruction may require a source operand, a destination operand or both. For 32-bit
segments, string instructions use ESI and EDI registers to point to the source and destination
operands, respectively.
For 16-bit segments, however, the SI and the DI registers are used to point to the source and
destination, respectively.
OUTPUT:
Solution :
.model small
.stack 100h
.data
msg1 db 'hello$'
msg2 db 'world$'
.code
main proc
mov ax, @data
mov ds, ax
mov dx,offset msg1
mov ah,9
int 21h
mov dx,10
mov ah,2
int 21h
mov dx,13
mov ah,2
int 21h
mov dx,offset msg2
mov ah,9
int 21h
mov ah,4ch
int 21h
main endp
end main
OUTPUT:
Practical No 16
Interrupt
An interrupt is actually a call to a subroutine, but initiated by the peripheral hardware itself and
not by the "CALL" instruction. The interrupt is asynchronous and can occur at any time during
the execution of the main program.
The interrupt handling is an alternative to a method known as "polling", which is reviewing the
status of each of the peripherals, over and over again in a continuous loop, to see if any of
them needs service.