0% found this document useful (0 votes)
69 views

Lyla B Das3pdf PDF

This document provides an overview of Chapter 3 of a programming concepts textbook. It discusses different approaches to programming problems, including top-down and bottom-up. It introduces some important DOS functions for input/output like reading keyboard input and displaying characters. It also outlines the instruction set of the 8086 processor, focusing on data transfer instructions. The chapter aims to help readers understand programming practices, use DOS functions in programs, and learn about different instruction types.

Uploaded by

aymanayman
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
69 views

Lyla B Das3pdf PDF

This document provides an overview of Chapter 3 of a programming concepts textbook. It discusses different approaches to programming problems, including top-down and bottom-up. It introduces some important DOS functions for input/output like reading keyboard input and displaying characters. It also outlines the instruction set of the 8086 processor, focusing on data transfer instructions. The chapter aims to help readers understand programming practices, use DOS functions in programs, and learn about different instruction types.

Uploaded by

aymanayman
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 46

CHAPTER 3

PROGRAMMING CONCEPTS-II

OBJECTIVES

The objectives of this chapter are

 To understand good programming practices


 To learn a few important DOS functions and use them in programs
 To understand a part of the instruction set of 8086
 To use data transfer instructions in different modes of addressing
 To understand the concept and importance of branch instructions
 To use unconditional and conditional branch instructions
 To understand and use the arithmetic instructions catering to unsigned numbers
 To use multiply and divide instructions for interesting applications
 To learn the use of logical ,shift and rotate instructions of the 8086

3.1 Approaches to Programming

We are now in a position to feel that we have understood to a small extent ,the tools
needed for programming (in this case assembly programming) .But before getting down
to the actual coding process ,it might be worthwhile to spend some time trying to
understand the various approaches to be used in programming . These ideas apply to all
levels of programming -i.e. whether we use high level languages or assembly level
languages.
One common argument is whether programming is an art or a skill . To say that it is an
art implies that good programmers are born ,not made . This may be partly true ,because
it is seen that some people have a natural flair for programming .But this applies to
almost every ability we might have .Even if programming skill is an inborn ability , one
has to polish it and practice this craft to become good at it .There is no other way but
hard work to become an expert .
Coming to the other side of the argument that programming is a skill -then also ,the same
rules apply . The craft of programming has to learned with sound basics - we should
develop our thought processes to become good problem solvers . For every problem
,there is more than one way of solving it .Finding the optimal solution depends to a great
extent on how much we have learned to build castles in the air -where these castles are
the solutions to our problems .
Let us conclude that just anyone can become a reasonably good programmer , by getting
a good grasp of the basics and following it up with keen studying and continuous
practice.
There are various approaches to solve a programming problem .One is called the top
down approach. This approach tends to look at the problem as one whole functional

x86 Chapter 3 1
block .The solution to the problem is planned , after the whole problem is thoroughly
understood . This functional block is then broken down to smaller blocks ,whose
functions are to be defined along the way .
The other approach is the bottoms up approach . Here the basic functional blocks which
are available or can be clearly defined ,are joined together to get the bigger module .Thus
small function blocks are integrated to form the top level entity .
Both these approaches have their advantages and disadvantages. Depending on the type
of problem at hand , the methodology has to be decided.

Now ,a tip and advice before getting started-

Something that is to be avoided is to jump to 'coding' as soon as a problem is presented .


What this means is that, we must first build the solution to our problem ,optionally in our
mind -but the best way is to write a pseudocode or draw a flow chart before writing the
actual code .In this way , our thought processes lead us to the algorithm to use . As we
become more familiar with programming ,we may gradually avoid pseudocodes or flow
charts for small programs , but use them for the more complex ones .

In this book ,only the coding part is done -it is left to the student to visualize or write the
algorithm ,as he chooses .

Assembly programming tips


From the previous chapter ,you might have got an insight into assembly programming
using MASM . Now we are in a position to get a better idea of the instruction set of 8086,
in a phased manner .
In chapter 2 , a few programs were run ,but we did not have any mechanism to display
the outputs .There was also no mechanism to take in data through the keyboard i.e
interactive programming could not be done There we used the debugger to access
memory and registers to verify if our results are as they should be . For entering data ,
we were supposed to store it in the data part of the segment being used . For a
programmer , this approach seems cumbersome . Interactive programming would have
been more fun and instructive. But there is a way out of this difficulty .
Let us see what it is.
3.1.2 BIOS and DOS function calls
Until now , we were viewing the 8086 processor as being connected only to
memory .i.e. physical memory which is RAM .But in reality ,the processor is also
connected to various input and output devices .For example ,the PC has the keyboard
and mouse as input devices .The video monitor is an output device . As
programmers ,we would like to input data into the processor using the key board and get
the results displayed on the video monitor . To do this , we need to have some way of
accessing these I/O devices ,which contain a lot of extra hardware . Luckily, there is
some ready made software available to handle this problem ,and they come in the form of
functions written to access Input and Output devices. The word BIOS may seem familiar .
BIOS (Basic Input Output System)consists of a set of functions written for this
purpose .Besides this ,there is another set of functions called DOS functions or DOS
interrupts . They are part of the DOS operating system. They are functions written for

x86 Chapter 3 2
accessing input and output devices, which are called in the form of software
interrupts .We have seen one such DOS interrupt which is the one that the .EXIT
statement gets translated to . i.e.
MOV AH ,4CH
INT 21H
In this , 4CH is the function number which has to be loaded into the AH register before
calling the interrupt with type number 21H .This function caused exiting the program
and returning to the DOS prompt.
In Chapter 6,we will see the logic of interrupts and their way of functioning . But in this
chapter, we will use a few DOS interrupts to aid us in the process of programming .
Using these simple DOS interrupts will help us get the feel of programming as we are
able to use the available input and output devices interactively. We will see that
assembly language programming can be fun In this chapter ,a few DOS function calls
will be introduced. BIOS interrupts will be used in later chapters.
3.1.3 Using DOS function Calls

We will start with three important function calls ,all of which are of interrupt type 21H
i)Read the keyboard with echo
MOV AH ,01
INT 21H
This call exits with the ASCII value of the key pressed ,being available in AL .
The key pressed is also echoed on the screen .
ii)Read Keyboard without echo
MOV AH ,08
INT 21H
This call exits with the ASCII value of the key pressed being available in AL .
The key pressed is not echoed on the screen

iii)Write a character to the standard display unit.


For this ,the ASCII value of the character to be displayed should be in DL.
MOV DL ,S’
MOV AH ,02
INT 21H
With this ,the character S is displayed on the video screen
iv) Display a character string on the standard display unit
The logical address DS:DX should point to the beginning of the string .
This is to be followed by the following instructions
MOV AH ,09
INT 21H

3.1.4 The Instruction set of 8086

The instruction set of the 8086 is reasonably large .Besides, each instruction can be used
in various addressing modes making the whole set larger . Knowing all the
instructions ,their format and their features is a key factor in becoming an expert
programmer .

x86 Chapter 3 3
Let us list out the general features of instructions which will become clearer as they are
explicitly earned.
i)Most instructions have two operands i.e. the destination and the source .
These can be registers or memory operands .But both operands cannot be
memory operands. Some instructions can also use immediate data as the source
operand.
iii) Certain instructions have only one operand mentioned which is either the
destination or the source . These can be register or memory operands ,but not
immediate data.
iv) There are instructions which have no operands explicitly mentioned in the
instructions .In that case ,some register is implicit in the usage of these
instructions.
To learn the instruction set ,the approach will to be list instructions based on their
functionality , learn their format and function, and then write a few programs using them.

3.2 Data transfer Instructions.

The list below ( Table 3.1)gives all the data transfer instructions of 8086 ,except the
input and output instructions ,which will be introduced in Chapter 5.

Sl Instruction format Function performed Flags


No affected
1 MOV dest,src Copy the contents of the destination None
(Move) to the source
2 LEA reg16,memory Load the offset of specified memory None
(Load Effective Address) location in the (16 bit)register
3 XCHG dest,src Exchange the contents of the None
(Exchange) destination and source
4 PUSH source Transfer one word from source to the None
(Push) stack top (SS:SP).
5 POP destination Transfers word at the current stack None
(Pop) top (SS:SP) to the destination .
6 LDS reg16,memory Load far pointer to DS and reg.. None
(Load to DS and register)
7 LES reg16,memory Load far pointer to ES and register . None
(Loads to ES and register)
8 LAHF Copy bits 0-7 of the flag register into None
(Load AH with flags) AH.
9 SAHF Transfer bits 0-7 of AH into the flag None
(Store AH with flags) register.
10 PUSHF Transfers the flag register onto the None
(Push flags) stack
11 POPF Pop word from stack into the flag None
(Pop flags) register
12 XLAT Replaces the byte in AL with byte None
(Translate) from a user table addressed by BX.

x86 Chapter 3 4
Table 3.1: List of 8086 data transfer instructions with format and function

A few of these instructions will be discussed in detail and used in programs here. The rest
will be used in later chapters.

3.2.1 MOV -Move


Usage : MOV destination ,source
This instruction causes the source content to be copied to the destination.
Remember that the data types of source and destination should match –both should be
either bytes or words.
Examples
MOV AX,CX ;copy CX to AX –this is a word operation
MOV AL,AH ; copy AH to AL –this is a byte operation
MOV AX,[BX] ;copy into AX the data in the address pointed by BX
MOV COST,DX ;copy the word in DX to the location labeled COST
. The use of the MOV instruction in the register and immediate addressing modes was
covered in Chapter 2 .Hence we will use MOV in other modes of addressing now.

Example 3-1

.MODEL SMALL ;select small model


.DATA ;start data segment
COSTP DB 67H ;store cost price
SELLP DB ? ;space for selling price
.CODE ;start code segment
.STARTUP ;start program

PROFIT EQU 25H ;define the profit

MOV AL,COSTP ;move COSTP to AL


ADD AL,PROFIT ;add PROFIT to AL
MOV SELLP,AL ;store the sum in SELLP

.EXIT ;exit to DOS


END ;end of program

Example 3.1 shows the use of the MOV instruction in the direct mode of addressing .
This mode uses a memory location as one operand . Here two memory locations labeled
COSTP and SELLP have been defined in the data segment .COSTP has a data byte
stored in it ,but SELLP is only allocated space for later storage .The first MOV
instruction gets the data byte in COSTP into AL. After adding a pre-defined constant
PROFIT to it ,the sum in AL is stored in SELLP .Both the MOV instructions use direct
addressing . At this stage , you need to remember that the assembler will do the
conversion of the labels to memory addresses.

x86 Chapter 3 5
Example 3.2

.MODEL SMALL ; select small model


0000 .DATA ; start data segment

0000 10 20 30 40 50 ARRAY DB 10H,20H,30H,40H,50H


; setup array
0000 .CODE ; start code segment
.STARTUP ;start program

0017 BF 0000 MOV DI,0 ;load DI with 0


001A 8A 85 0000 R MOV AL,ARRAY[DI] ;get first element in AL
001E 04 07 ADD AL,07H ;add 07 to it
0020 BF 0005 MOV DI,05H ;add 5 to DI
0023 88 85 0000 R MOV ARRAY[DI],AL ;move sum to memory

.EXIT ;exit to DOS


END ;end of program

Example 3.2 shows the list file of a program which uses the MOV instruction in the
register relative addressing mode. Let us analyze the program The data segment is first
initialized with 5 bytes .The address of the first location is labeled as ARRAY ..DI is
used to address the element numbers .With DI=0 ,the first element is accessed ,and with
DI=5 ,the sixth element is accessed. Then the effective address (EA) is [ARRAY+DI] .
When DI=0, the instruction MOV AL,ARRAY[DI] ,transfers the data in the first memory
location to AL. To this , 07 is added. With DI=5, ARRAY[DI] becomes the effective
address of the sixth location in memory . Then MOV ARRAY[DI], AL stores the sum
in memory .
.The displacement for the relative mode is the value of the label ARRAY . From the list
file ,it is seen the offset corresponding to ARRAY is 0000..
Since ARRAY is the address of the first location in the data segment ,the data segment
will look like this ,after the program is executed. The sum will be in the location
ARRAY+5 .

EA CONTENT
ARRAY+5 17H
ARRAY+4 50H
ARRAY+3 40H
ARRAY+2 30H
ARRAY+1 20H
ARRAY +0 10H

x86 Chapter 3 6
Example 3.3
.MODEL SMALL ;select small model
0000 .DATA ;start data segment
0000 34 87 56 05 07 ARRAY DB 34H,87H,56H,05H,07H
;setup array
0000 .CODE ;start code segment
.STARTUP ;start program

0017 BB 0000 R MOV BX,OFFSET ARRAY ;address ARRAY


001A BF 0000 MOV DI,0 ;load DI with 0
001D 8A 01 MOV AL,[BX+DI] ;get first data
001F 04 35 ADD AL,35H ;add 35H to it
0021 BF 0005 MOV DI,05 ;address new location
0024 88 01 MOV [BX+DI],AL ;move sum here

.EXIT ;exit to DOS


END ;end program

Example 3.3 is the list file of a program that performs the same function as the previous
example ,but uses the based indexed mode of addressing .i.e. the effective address is the
sum of a base register and an index register . The instruction MOV BX, OFFSET
ARRAY causes the offset of ARRAY (which is 0000 as seen from the list file)to be
loaded into BX .Thus BX now is a pointer to the location labeled as ARRAY .But to
point to each element one by one ,another register DI is also used. With DI=0 ,the
instruction MOV AL, [BX+DI] causes the data in the first location to be copied to AL.
With DI=5 ,[BX+DI] accesses the sixth location in the data segment .

3.2.2 LEA –Load Effective address


Usage: LEA reg16, memory
This instruction causes the offset of the specified memory location to be loaded in the
indicated register.
Examples
LEA SI,COSTP ;load the offset of memory location COSTP in SI
LEA BX, ARRAY ;load the offset of memory location ARRAY in BX
You may notice that the above is a replacement for the instruction
MOV BX, OFFSET ARRAY used in Example 3.3 .

Now let us use this instruction in an interesting application.


We would like to display two character strings on two lines on the video monitor . It
was discussed in Section 3.1.2 that DOS function calls are needed for this . The following
is the list file for the program which does this.

x86 Chapter 3 7
Example 3.4(a)
.MODEL SMALL
0000 .DATA
0000 48 45 4C 4C 4F 24 MESG1 DB "HELLO$"
0006 0A 0D 49 20 41 4D MESG2 DB 0AH,0DH,"I AM SAM$"
20 53 41 4D 24
0000 .CODE
.STARTUP

0017 8D 16 0000 R LEA DX,MESG1 ;load offset of MESG1 in DX


001B B4 09 MOV AH,09H ;DOS function number for
001D CD 21 INT 21H ; displaying a string

001F 8D 16 0006 R LEA DX,MESG2 ;load offset of MESG2 in DX


0023 B4 09 MOV AH,09H
0025 CD 21 INT 21H

.EXIT
END

Example 3.4(b)

HELLO
I AM SAM
C:\masm6.14\BIN>

Now let us analyze the program that does this ,the listing of which is shown in Example
3.4(a).
In the data segment ,two messages are stored at offsets with labels MESG1 and MESG2
.The character strings are enclosed in double quotes and terminated by the $ sign .This
sign is mandatory to end a character string which is to be printed on the display device ..
Notice that the listing in Ex 3.4a shows the corresponding ASCII values for each
character of the string. On the second line , we see two characters 0AH and 0DH .These
are the ASCII values for line feed(which advances the cursor to the next line) and
carriage return (sets cursor to the left position of screen).These are necessary for
printing to occur on the second line, starting from the left.
To print the first message ,DX points to the offset MESG1 This is done by using the LEA
instruction ,which loads the offset of MESG1 in DX.. Then the DOS function with
number 09 is called .Similarly for the second message ,DX should point to the offset of
MESG2.

The two messages as they are printed on the command window is seen in Example
3.4(b). The .EXIT command causes control to return to DOS prompt

3.2.3 PUSH and POP

Usage : PUSH source


POP destination

x86 Chapter 3 8
For the 8086 ,only 16 bit data can be pushed and popped.
Note : CS is not a valid destination for POP.
Examples:
PUSH BX ; save the contents of BX to stack
PUSH [BX ] ;save to stack the contents of the word pointed
;by BX
PUSH DS ; save to stack the contents of the segment
; register DS
PUSH COSTP ;save to stack the contents of the word
;location COSTP
POP CX ;load the contents of the stack top to CX
POP [SI] ;load the contents of the stack top to the
;memory location pointed by SI

The PUSH and POP instructions are relevant only for the stack segment . The stack is a
region of temporary storage .When a subprogram is called ,the register contents of the
main program at that point of time and the current value of IP and CS are pushed onto the
stack ,and retrieved on returning from the sub program .These things are done
automatically as part of a CALL instruction .Besides this ,a programmer can opt to store
in stack temporarily the values of some registers ,so that he can use those registers for
other computations . He can get back the previous values of these registers ,after he
completes his current computation . These operations are accomplished by the PUSH and
POP instructions.
The 8086 ,as mentioned in Chapter 1 , uses a Last in First out(LIFO)stack . A stack is an
area of memory , in which the lowest address is the base address of the segment .The
upper 16 bits of this base address will be in the SS register .The highest address will be in
the SP register –or rather ,the SP will contain the offset of the highest address with
respect to the base address .This is why it is called the TOP of STACK . For example, if
the stack is defined from addresses 20000H to 203E8H , SS=2000H and
SP=03E8H,.This stack then has a size of 3E8H bytes or 1000 bytes.
In the 8086 ,only a word (16 bits ) can be pushed on to stack . A push thus causes two
memory locations to be accessed .
The operation of the stack is different from normal memory operations. It is a push-down
memory . i.e. For the value of SP mentioned above ,let us say ,the PUSH BX instruction
is to be executed . Let BX=CC99H. .Recollect that SP=03E8H.
The operation of pushing is as follows SP is first decremented by two . The new data
will be put in addresses (offsets ) 03E7H (SP-1) and 03E6H(SP-2), adhering to the
‘ little endian’ concept i.e. the higher byte of BX will be the higher address (03E7H) and
the lower byte in the lower address (03E6H).The new value of SP will be 03E6H . This
shows that new data to be pushed onto the stack will be pushed in the lower two
addresses with respect to the current stack top. Always ,the stack top (SP) has the offset
corresponding to the last byte that was pushed in .

BX
CC 99

x86 Chapter 3 9
CONTENTS ADDRESS OF
OF STACK STACK TOP

-- 03E8H SP BEFORE
THE PUSH
CC 03E7H
99 03E6H SP AFTER THE
PUSH
---- 03E5H
--- 03E4H

Fig 3.1 PUSH operation in a stack

The reverse will be the case after a POP operation. Assume a POP CX operation at a
time when the SP value is 0312H . The content of the stack will be loaded into the CX
register. ,and SP is incremented by two.

CONTENTS ADDRESS OF
OF STACK STACK TOP

-- 0314H SP AFTER
THE POP
0E 0313H
67 0312H SP BEFORE
THE POP
---- 0311H
--- 03E10H

CX
0E 67

Fig 3.2 :POP operation in a stack

Defining a stack
Now ,how will we use the stack in programming?
Obviously we have to define the stack size ,base address of segment ,stack top etc . If we
are using the tiny segment ,this is done for by DOS –but in other memory models ,we
will have to do it ourselves ..In case we don’t , a warning ‘No stack segment’ will
appear on assembling .This can be ignored if the stack size is less than 128 bytes

x86 Chapter 3 10
.Otherwise , the stack that gets defined by DOS may erase the PSP and cause the system
to crash .

Example 3.5 a
.MODEL SMALL
.STACK 400H ;specify stack size

Example 3.5b

STACKSEG SEGMENT STACK

DW 200H (?)

STACKSEG ENDS

Example 3.5 shows two ways of defining a stack. Ex 3.5a uses the simplified memory
model and it specifies the size of the stack as 400 bytes .Ex 3.5 b uses the full segment
definition .200 data words are to be set aside as stack ,as per this definition. Here, both
definitions create stacks of the same size.

Example 3.6
Explain what is done in this program .Assume SP =0310H ,when the stack was initialized
.MODEL SMALL
.STACK 300H
.CODE
.STARTUP
MOV AX,4567H
MOV BX,0ACEH
PUSH AX
PUSH BX
POP AX
POP BX
.EXIT
END

Solution:
This program defines a stack of 300 bytes by the use of the stack directive
The program first loads two numbers in AX and BX. These numbers are pushed into
stack using the PUSH operations . Then comes the POP operations .What we need to
remember is that popping occurs in the reverse direction. What is pushed in last will be
popped out first .The last PUSH was PUSH BX ..It is obvious then that by the POP AX
operation ,the content of AX is replaced by the content of BX .Similarly the second POP
causes BX to get the content of AX. Thus this program exchanges the content of these

x86 Chapter 3 11
two registers , using the stack as a temporary data storage area. After execution the
contents of the registers are: BX=4567H and AX=0ACEH .
Note: Exchanging register contents is not really an application for the stack .We can
exchange these register contents easily by using the instruction XCHG AX,BX
But this program shows the relationship between POP and PUSH operations.

3.3 BRANCH INSTRUCTIONS


Branch instructions are very important ,because they carry on them the full power of a
computer . Branching can be conditional or unconditional .Unconditional branching
becomes necessary when looping back or forward is done infinitely ,like when we use
software to generate a square wave continuously .But most of the time , conditional
branching is what may be more important . Taking decisions based on the result of a
computation is what gives computers their power and versatility . Most instructions that
we will use subsequently become meaningful only when conditional branching is used.
In this chapter ,we will discuss only the jump and loop instructions .Other branching
instructions like call and return will be discussed in Chapter 4.
We will start with the jump instruction.
3.3.1 JMP -Jump
Usage: JMP destination
The destination is a memory location ,which can be expressed in different ways as will
be discussed presently .The jump destination is frequently referred to as ‘target’ as well.
A jump instruction breaks the normal sequence of program execution ,and takes control
to a different location in the code segment .
MOV…..
ADD,-----
JMP AGAIN
………..
--------
-
-
------------
AGAIN: ……..

Figure 3.3 : Control flow using the jump instruction


There are many ways and restrictions in specifying the target value ,and based on
this ,we can have different types of jumps . Fig 3.3 above could be a typical scenario.
When the ADD instruction is being executed , IP(Instruction Pointer) points to the next
instruction which is an unconditional JMP instruction .On decoding the JMP
instruction ,the EU(Execution Unit) realizes that the next instruction should be taken
from the location with label AGAIN . It is obvious then , that the IP content must be
changed in such a way that a new sequence is to be followed .
The salient points regarding jump are :
i) The jump location may be in the same code segment ,in which case it a near
jump. For a near jump ,the value of CS remains the same ,but the value of IP

x86 Chapter 3 12
will change. This also called an intrasegment (within segment) jump.
ii) The jump location may be in a different code segment –then it is called a far
jump .In this case , both CS and IP will have to take on new values. This is an
inter-segment (between segments) jump.
iii) The label of the destination address should be followed by a colon.
iv) Jumping can be backward or forward in the program sequence
v) Jumping can be unconditional .Then the format of the jump instruction is
JMP label ,where label is the address of the destination
vi) Besides unconditional jumps, there are a number of conditional jumps
available .The conditions are based on the state of the flags which get affected
by arithmetic or logic instructions.

The Near Jump


In the direct mode of addressing ,the near jump has the format
JMP label where the label is the address of a memory location.
The destination can be a 16 bit signed number ,which means that range of jumping is
within +/- 32K bytes . . In direct jump ,the jump location is a signed displacement from
the current value of IP to the destination address. i.e. the assembler calculates this
displacement ,and adds it to the current IP value .Thus the jump address is relative or
rather ,re-locatable .For a forward jump ,this displacement will be positive ,while for a
backward jump ,this will be negative It uses three bytes as instruction size –one byte for
the opcode ,and two bytes for the 16 bit destination offset.

OPCODE OFFSET LOW OFFSET HIGH

NEW IP =CURRENT IP + OFFSET (16 bit)

Fig 3.4 : Format of the near jump instruction

The Short Jump


The short jump is a special case of a near jump with the format JMP destination . , For
short jumps ,the displacement must be an 8 bit signed number ,which means that the
jump destination can only be -128 or +127 bytes displaced from the current value of IP.
A directive SHORT can be used if we are sure that our jump destination is within the
above specified range This instruction is two bytes long .-i.e. one byte for the opcode and
one byte for the destination offset.

OPCODE OFFSET

NEW IP =CURRENT IP + OFFSET (8 bit)

x86 Chapter 3 13
Fig :Format of the short jump instruction

Now let us see an address calculation for a short jump instruction

EXAMPLE 3.7

0000 B4 01 BEGIN: MOV AH,01


0002 CD 21 INT 21H
0004 8A D0 MOV DL,AL
0006 EB 07 JMP SHORT THERE
----------------------------------------
--------------,skipped instructions>---
----------------------------------------
000F 80 C2 02 THERE: ADD DL,02
0012 B4 02 MOV AH,02
0014 CD 21 INT 21H
0016 EB E8 JMP SHORT BEGIN

Example 3.7 shows how short jump instructions pass control from one part of the
program to another. During the time that the instruction JMP SHORT THERE is
decoded, the IP value is 0008 (address of the next instruction) . During the beginning of
the first pass ,the assembler reserves one byte for the address of THERE. The assembler
knows that only one byte is required for THERE ,because of the directive SHORT.
.Otherwise ,it would have reserved two bytes space ,as for a general near jump. If the
address of the next instruction (0008) is added to the sign extended displacement (0007)
of the first jump(this displacement is calculated by the assembler) ,the address of THERE
is at location 0008H + 0007H = 000FH . Thus control branches to location 000FH.
JMP BEGIN is seen to be a backward jump .The assembler calculates this displacement
(which is negative) and add this displacement to the value of IP at that point of the
instruction sequence. Then it jumps to the destination BEGIN. In this case the negative
displacement is E8H .When JMP SHORT BEGIN is executed ,IP value will be 0018H .
For jumping to BEGIN, the address calculation is 0018+FFE8=0000 ,which is the
address of the instruction with the BEGIN label .Note that the negative number
E8H ,when used in 16 bit calculations ,has to be sign extended. So E8H is FFE8H in
16 bit sign extended form.
Now let us write and run a fun program using an unconditional jump instruction.
Example 3.8 is a simple program named UPLOW which uses DOS interrupts to enter a
character from a key board . If this character is an upper case alphabet ,it converts it to
lower case . The ASCII character table shows that a lower case character can be obtained
by adding 20H to the upper case code .i.e. The ASCII of ‘A’ is 41H and that of ‘ a’ is
61H ,and so on .

Example 3.8a

x86 Chapter 3 14
.MODEL TINY
.CODE
.STARTUP
START: MOV AH,01H ;AH=01
INT 21H ;enter a key
ADD AL,20H ;add 20H to it
MOV DL,AL ;move the sum to DL
MOV AH,02 ;AH=02
INT 21H ; use this function to display
MOV DL,0AH ;0AH is the ASCII for newline
MOV AH,02H ;display a new line
INT 21H
JMP START ;go to start to repeat
.EXIT
END

Example 3.8b

C:\masm6.14\BIN>UPLOW
Aa
Bb
Cc
Dd
Ee
Ff
Gg
Hh
^C
C:\masm6.14\BIN>

INT 21H with function number 01 is used to enter a key .Then 20H is added to the
ASCII value of the key ,and this is displayed in the same line . To get further displays on
separate lines ,the ASCII character 0AH is displayed .Remember that 0AH corresponds
to ‘newline’. The JMP START instruction is used to repeat this whole sequence
indefinitely .Since there is no stopping condition for this loop ,we have to use the ’ctrl c’
combination of the key board to terminate the program . The displayed output is shown
in example 3.8b ,Note that ,for any key input other than an upper case character ,the
output is some random character.

Other forms of the unconditional jump instruction

There are other modes of addressing for the near jump .


i) JMP reg16
This is called an indirect jump .The 16 bit register contains the destination address
(offset).This jump is not a relative jump .IP gets replaced by the value in the register .
Example
JMP BX ;jump to the destination address in BX .Make IP=BX
JMP SI ;jump to the destination address in SI .Make IP=SI

x86 Chapter 3 15
ii) JMP [reg 16]
This is like a double indirect jump .The register points to an address which contains the
jump location .

Example
JMP [SI] ;jump to the address which is stored in the memory location pointed
;by SI
If SI =0670H , the destination address is taken from the data segment at locations 0670H
and 0671H. IP is replaced by the value at these addresses.

CONDITIONAL JUMPS

Conditional jumps are the best part of the idea of control transfer .They change the
sequence of program execution based on the result of a computation which causes flag
bits to be set or reset .However ,there is one case (JCXZ) where a register content is
checked.
Note: All conditional jumps are short jumps
.
Usage : J(condition) destination

Table 3.1 contain the jumps used for unsigned data ,and those directly testing flags and
registers.

Sl Mnemonic What it means Condition tested


No
1 JA Jump if Above CF=0 and ZF=0
2 JAE Jump if Above or Equal CF=0

3 JB Jump if Below CF=1


4 JBE Jump if Below or Equal CF=1 or ZF=1

5 JC Jump if Carry CF=1


6 JCXZ Jump if CX Zero CX=0
7 JE Jump if Equal ZF=1
8 JNA Jump if Not Above CF=1 or ZF=1
9 JNAE Jump if Not Above or CF=1
Equal
10 JNB Jump if Not Below CF=0
11 JNBE Jump if Not Below or CF=0 and ZF=0
Equal
12 JNC Jump if No Carry CF=0
13 JNE Jump if Not Equal ZF=0
14 JNP Jump if No Parity PF=0
15 JNZ Jump if Not Zero ZF=0

x86 Chapter 3 16
16 JP Jump if Parity PF=1
17 JPE Jump if Parity Even PF=1
18 JPO Jump if Parity Odd PF=0
19 JZ Jump if Zero ZF=1
.
Table 3.2 List of conditional jump instructions which cater to unsigned arithmetic/
directly address flags or registers

Note
i) Certain mnemonics are equivalent–For example ,JZ and JE mean the same as
they test the same flags. So also JC and JB , JP and JPE etc. More can be
identified from the list.

ii) JCXZ tests the CX register but other Jump instructions test conditional flags
only.

iii)There is another set of conditional jump instructions which are specially meant
for signed arithmetic .The list of those instructions and their usage will be dealt
with, in Chapter 4.

We will use a few of the conditional jumps in the forthcoming examples.

FAR JUMP
A far jump is an intersegment jump ,which means that the destination address is in a
different code segment .
This will be a five byte instruction ,the first byte being the opcode ,the second and third
the new value of IP ,and the fourth and fifth the new values of CS.

OPCODE IP LOW IP HIGH CS LOW CS HIGH

Fig 3.6: Format of the far jump instruction


To specify that a jump is to a different code segment , a far pointer can be used in the
format
JMP FAR PTR AGAIN ;PTR stands for ‘pointer’

Defining an address as external and then using a jump to this address is also possible .
These ideas will be discussed in Chapter 5.

3.3.2 The LOOP instruction

x86 Chapter 3 17
Usage : LOOP label
There is a very useful and frequently used instruction called LOOP .This combines jump
with a counter .The register CX is assigned to decrement every time LOOP executes.
When CX=0 ,the looping is exited.

MOV CX,N
MORE: ……..
--------
…………
………..
LOOP MORE
……………….
…………………

In the above, control returns to the label MORE ,and the sequence of instructions up to
the LOOP instruction will be repeated until CX becomes equal to zero .
LOOP can be combined with other conditions ,to make it a conditional instruction.
LOOPNE/ LOOPNZ , LOOPE/LOOPZ etc can be used. These instructions test the zero
flag ,as well as the value of CX
Example 3-9 shows the use of an unconditional LOOP instruction.
In this program , three arrays have been declared in the data segment .Corresponding
bytes from the first two arrays are to be added and the sum is to be saved in the third
array . To point to the data items in the three arrays ,three registers are used . Data is
accessed using register indirect addressing .After one round of these actions ,the pointer
registers are incremented using the INC instruction .This instruction adds 1 to the
registers . This sequence of operations is repeated six times ,by using the LOOP
instruction .Once CX=0 ,the loop is exited ,and the program ends.

Example 3.9a

.MODEL SMALL
.DATA

NUMS1 DB 45H,67H,89H,65H,34H,23H
NUMS2 DB 09,09,12H,13H,08,02
NUMS3 DB 6 DUP(0)
.CODE
.STARTUP

LEA BX,NUMS1 ;use BX to point to NUMS1


LEA SI,NUMS2 ;use SI to point to NUMS2
LEA DI,NUMS3 ;use DI to point to nUMS3
MOV CX,06 ;CX=6
REPEA: MOV AL,[BX] ;take into AL data from the array NUMS1
ADD AL,[SI] ;add to AL the data in array NUMS2
MOV [DI],AL ;save the sum in the third array
INC BX ; increment pointer
INC SI ; increment pointer
INC DI ; increment pointer

x86 Chapter 3 18
LOOP REPEA ;repeat the sequence until CX=0
.EXIT
END

This problem can be done with less number of address registers if ‘register relative
mode’ of addressing is used .See Example 3.9b.Here only the register BX is used .Its
content is added to different addresses so as to access the three different arrays.
Example 3.9b

.MODEL SMALL
.DATA

NUMS1 DB 45H,67H,89H,65H,34H,23H
NUMS2 DB 09,09,12H,13H,08,02
NUMS3 DB 6 DUP(0)
.CODE
.STARTUP

MOV CX,6
MOV BX,0
REPEA: MOV AL,NUMS1[BX] ;point to the first array
ADD AL, NUMS2[BX] ;add numbers of the second array
MOV NUMS3[BX] ,AL ;save in the third array
INC BX
LOOP REPEA ;repeat until CX-0
.EXIT
END

Now ,we will digress to the discussion of arithmetic instructions ,but you can see that
branch instructions in various forms will be continued to be used.

3.4 ARITHMETIC INSTRUCTIONS


The complete list of arithmetic instructions is given in Table 3.3. Instructions from 1 to 9
will be discussed in detail and used in this chapter .The rest will be dealt with , in Chapter
4 for signed number arithmetic.
Note
i) In the list ,dest means destination and src means source.
After an operation ,the result is available in the destination.
iii) As mentioned earlier ,the destination and source may be both registers or a
memory location and a register. If the destination is a register the source can .
be immediate data, unless explicitly mentioned (for certain instructions)that
immediate mode of addressing is not allowed.
iv) Flags are affected by most of the arithmetic instructions, In certain cases ,all
flags are affected ,but some flags are undefined .The --- notation for the
corresponding flags is used in such cases meaning ‘undefined’.(in the table)
iii) In certain cases ,flags are not affected .This is specified by ‘none’

No Instruction Format FUNCTION PERFORMED FLAGS AFFECTED

x86 Chapter 3 19
1 ADD dest,src Add dest and src AF CF OF PF SF ZF

2 ADC dest,src Add dest ,src and CF AF CF OF PF SF ZF


3 INC dest Add 1 to the destination AF -- OF PF SF ZF
4 SUB dest,src Subtract src from dest AF CF OF PF SF ZF
5 SBB dest,src Subtract source and CF from dest AF CF OF PF SF ZF
6 DEC dest Subtract 1 from dest AF --- OF PF SF ZF
7 CMP dest ,src Subtracts source from destination and AF CF OF PF SF ZF
updates the flags but does not save result.
Only flags are affected
8 MUL src Unsigned Multiply --- CF OF -- --- ---
9 DIV src Unsigned binary divide -- -- --- --- --- --
10 CBW Convert byte to word None
11 CWD Convert word to double word None
12 DAA Decimal Adjust for Addition- AF CF -- PF SF ZF

13 DAS Decimal Adjust for Subtraction. AF CF -- PF SF ZF

14 NEG dest Two's Complement Negation AF CF OF PF SF ZF


15 IMUL src Signed Multiply --- CF OF -- --- ---
16 IDIV src Signed Integer Division -- -- --- --- --- --
17 AAA ASCII Adjust for Addition AF CF -- --- --- --
18 AAS ASCII Adjust for Subtraction AF CF --- --- -- --
19 AAM ASCII Adjust for Multiplication --- --- PF SF ZF
20 AAD ASCII Adjust for Division SF -- -- PF --- ZF

Table 3.3 : Full set of arithmetic instructions

FLAG CONTROL INSTRUCTIONS

There are certain instructions which can be used to set/reset flags .This is very relevant
in the case of control flags like direction flag ,interrupt flag etc . But one conditional flag
can also be set /reset using instructions ,and that is the carry flag. The relevant
instructions for it are:
i) CLC -Clear carry
ii) STC -Set Carry
iii) CMC -Complement carry

Now we will see the format and usage of some of the important and commonly used
arithmetic instructions.

3.4.1 ADDITION INSTRUCTIONS

x86 Chapter 3 20
1)ADD -Add
Usage: ADD destination ,source
This instructions adds the destination and source and puts the sum in the destination. All
conditional flags get affected.
Examples
ADD AH,AL ;add AL to AH ,sum in AH
ADD AL, COSTP ;add the byte in COSTP to AL ,sum in AL
ADD BX,0987H ;add the number 987H to BX ,sum in BX
ADD CX ,[BX ] ;add the word in the location pointed by BX to CX
;sum in CX
2) ADC –Add with carry
Usage: ADC destination ,source
This instruction adds CF and source to the destination ,and puts the sum in the
destination. There are three operands ,of which the third is the carry . All conditional
flags get affected
Examples
ADC AH,0 ; AH=AH+0+CF
ADC [BX],AL ;add the byte pointed by BX with AL, and CF .
;put sum in the location pointed by BX
ADC AX,[BX][SI] ;add to AX , CF and the word with EA=BX+SI
3)INC -Increment
Usage: INC destination
This instruction adds 1 to the destination . All conditional flags except the carry flag
get affected.
INC BX ;add 1 to the content of BX
INC [BX] ;add 1 to the content of the memory location pointed by BX
INC AH ;add 1 to the content of AH

The PTR directive


This is a convenient point to introduce the PTR (pointer) directive .When the size of
the operand is not implicit in the instruction ,a pointer is used to indicate whether the
operand is a byte ,word ,or doubleword.. For example ,see the instruction
INC [BX]
Here BX is a pointer to a location whose content is to be incremented .It is not clear
whether the data being pointed to ,is a byte or word or dword .To make it clear ,it will be
helpful to modify the instruction as
INC BYTE PTR [BX] ;byte pointer
or INC WORD PTR[BX] ;word pointer
as the case may be . We will encounter various instances where this pointer is used.

Example 3.10

x86 Chapter 3 21
The following is a program which adds two bytes stored in memory . The sum of the
bytes is likely to be greater than FFH. Hence a word space needs to be allocated for the
sum.

.MODEL SMALL
.DATA
NUMS DB 95H ,0FCH ;store the two bytes
SUM DW ? ;allocate a word space for the sum
.CODE
.STARTUP
MOV AX,0 ;AX=0
CLC ;clear the carry flag
MOV AL,NUMS ;move the first number to AL
ADD AL,NUMS+1 ;add the second number to AL
ADC AH,0 ;add AH and CF and 0
MOV SUM,AX ;the sum in AX is moved to memory
.EXIT
END

First AX is loaded with 0.Observe how a byte addition causes a result to be a word .The
sum of two bytes which are added to AL is too large to fit in AL. Hence it generates a
carry .The next instruction adds CF ,0 and AH which contains a 0. So we find that the
carry bit is accommodated in AH .Thus AH-AL i.e. AX contains the sum which is a
word.

Example 3-11 adds 10 bytes stored in memory . The sum of these ten bytes will not fit
into a byte location .So a word location is allocated for the sum .It must also be noted
that the sum will definitely fit into a word location .[ If there are ten bytes ,the maximum
number possible for the sum of ten bytes is only 255 x10 =2550 ,which is less than
65,536 the maximum decimal number that a word can hold]

Example 3.11
.MODEL SMALL
.DATA
NUMS DB 245,178,190,167,56,178,250,89,150,235
SUM DW 0
.CODE
.STARTUP
CLC ;clear the carry flag
LEA BX,NUMS ;BX to point to the numbers
MOV CX,10 ;move the count to CX
MOV AX,0 ;make AX=0
REPEA: ADD AL,[BX] ;add the numbers ,sum in AX
ADC AH,0 ;add the carries into AH
INC BX ;increment the pointer
LOOP REPEA ;repeat if CX is not equal to 0
MOV SUM,AX ;store AX in SUM

x86 Chapter 3 22
.EXIT
END

The above is a simple program which gives a lot of information .


For one thing ,note that data is written in the decimal form ,and not as hexadecimal
bytes .But if the list file is checked, it will show that the data is converted to
hexadecimal format (in the machine code part of the listing)
The program uses the LOOP instruction to carry out cumulative addition . CX is used as
a counter, which decrements with each addition .The first ADD instruction adds two
bytes .It is possible that a carry is generated out of this addition This carry is added to
AH ,the other operand of which is 0 .Thus the sum of the carries of the ten addition
operations will be in AH ,which will form the upper byte of the sum .This sum is thus
available as a word in AX which is saved in the word location SUM. It is important to
clear the carry flag before using the ADC instruction ,to avoid the possibility of any
residual carry leading to a wrong result.

Example 3.12 is an interesting program which adds two double words .A doubleword is
two words long .i.e 4 bytes long .

Example 3-12
.MODEL SMALL
.DATA
LONGNUM1 DD 0F8FC6768H ;first double word data
LONGNUM2 DD 0C6EF2109H ;second double word data
SUM DD 0 ;sum
SUMC DB 0 ;space for carry out
.CODE
.STARTUP
LEA SI,LONGNUM1 ;SI as pointer to first operand
LEA DI,LONGNUM2 ;DI as pointer to second operand
LEA BX,SUM ;DX as pointer to the sum
CLC ; clear carry
MOV CX,2 ; CX to count the number of words
REPEA: MOV AX,[SI] ;move to AX the first word
ADC AX,[DI] ;add the second operand and carry
MOV[BX],AX ;the lower word of result stored
INC SI ;increment SI twice to point to
INC SI ;next word operand
INC DI ; increment DI twice to point to
INC DI ;second word operand
INC BX ;increment BX twice to point to
INC BX ;second word of the sum
LOOP REPEA ;go back if CX is not 0
MOV DL,0 ;make DL=00
ADC DL,0 ;add the carry to DL
MOV SUMC,DL ;move the carry to SUMC
.EXIT
END

x86 Chapter 3 23
There are a number of notable features for this program .
Let us list out these features.
i) The double words are stored in two DD locations named LONGNUM1 and
LONGNUM2 . They will be stored in the little endian format.
ii) The sum of two doublewords can be more than a double word. This can be
accommodated as a carry ,added to a register ,and can be stored in memory
as the uppermost byte of the sum. Three registers are used as pointers to each
double word .However ,addition can be done only as words . Hence, first the
lower order words of the two double words are added .There is a possibility
of a carry due to this addition ,which may have to be added to the upper
word.
Since addition is looped, the ADC instruction is used so as to accommodate
the addition of this carry into the upper byte.
iii) The address pointers have to be incremented by 2 to point to the upper word
of the double word .The INC instruction is preferred over the ADD
instruction ,as it does not affect the carry flag .It is important to preserve the
carry bit out of the second word operation . This carry is added to DL (which
is first ensured to be 0).
The numbers used herein are two double words whose sum is a double word ,
plus a byte (01 BFEB 8871H)
iv) The memory locations and the corresponding data ,after program execution
is as shown(assuming the origin of the data segment is 0000)
v) The three arrays in memory can be accessed by using ‘register relative
addressing ‘ as is Example 3-9b. Try to see if it gives any advantage in terms
of reducing the number of instructions/registers used.

OFFSETS IN DS DATA
000C 01 SUMC
000B BF
000A EB
0009 88 SUM
0008 71

0007 C6 LONGNUM2
0006 EF
0005 21
0004 09

0003 F8 LONGNUM1
0002 FC
0001 67
0000 68

x86 Chapter 3 24
Table: 3.4 Relevant portion of the data segment after the execution of Example
3.12

3.4.2 SUBTRACTION
1)SUB -subtract
Usage : SUB destination ,source
This instructions subtracts the source from the destination .The result is in the
destination. All conditional flags are affected
Examples
SUB AX,BX ;subtract BX from AX
SUB AL,[BX] ;subtract the byte pointed by BX from AL
SUB CX,COST[SI] ;subtract from CX the word with EA=COST+SI
SUB AX,8956H ;subtract 8596H from AX
SUB CL,BYTE PTR [SI] ; subtract from CL the byte pointed by SI

2) SBB –subtract with borrow


Usage: SBB destination ,source
This instruction subtracts the source and the carry flag from the destination .
All conditional flags are affected .
SBB CH,7 ;subtract from CH 7 and CF –result in CH
SBB AX,]BP+2] ;subtract from AX ,the word pointed by [BP+2]
;Since BP is used ,the data is taken from the
; stack segment .The result is put in AX
3) DEC -decrement
Usage : DEC destination
This instruction subtracts 1 from the destination
All conditional flags except the carry flag ,are affected.

DEC CL ; subtract 1 from CL


DEC WORD PTR [SI] ;subtract 1 from the word pointed by SI
DEC BYTE PTR NUMB[BX] ;subtract 1 from the byte pointed by the
;effective address NUMB+BX

Example 13 .13

Explain what occurs on execution of the following instructions


MOV CL,0B5H
SUB CL,0FCH

Solution
B5 H 181 D 1011 0101
- FC H - 252 D 1111 1100
B9 H -71 D 1011 1001

x86 Chapter 3 25
This is a subtraction of a bigger number from a smaller number .Hence the carry flag is
set to indicate that a borrow has been used in the subtraction. The difference is -71
(decimal),which is represented as B9H which is the two’s complement representation of -
71 D. The carry flag is set in indicate that the subtraction has used a borrow .The sign
flag is set to indicate that the MSB of the result is 1 ,which ,in this case is interpreted to
be a negative number.

Now Let us use the SUB instruction in an interesting example .


Division is an operation which can be achieved by repeated subtraction .Many early
microprocessors (8085 ,for example) had no divide instruction. The 8086 ,however has a
divide instruction .But here ,let us use repeated subtraction to divide say ,100 by 9 . We
know that the quotient is 11 (0BH) and the remainder is 1 .

Example 3.14

.MODEL SMALL
.DATA

QUOTIENT DB 0
REMAINDER DB 0

.CODE
.STARTUP
MOV AL,100 ;copy dividend to AL
MOV CL,0 ;CL ,the quotient register=0
REPEA: SUB AL,9 ;subtract 9 from 100
JC OVER ;stop when CF =1
INC CL ; increment CL if CF is not set
JMP REPEA ;repeat subtraction if CF is not set
OVER: ADD AL,9 ;add 9 to AL to get remainder
MOV REMAINDER,AL ;store remainder
MOV QUOTIENT,CL ;store quotient
.EXIT
END

The steps of the program are as follows


i) Subtract 9 from 100 repeatedly until a negative number is obtained .In the
program ,start with AL=100 .When AL becomes negative ,the carry flag will
be set (due to borrow) .This is the stopping condition for subtraction.
ii) In this problem , after subtracting 9 from 100 eleven times , AL will contain
01 . One more subtraction will cause the content of AL to become -8 (F8H
in 2’s complement form) . The carry flag is found to be set ,and further
subtraction is stopped.
iii) To get the remainder, add 9 (the divisor ) to AL . We get 1 .This is the
remainder
iv) Every time a subtraction is performed unhindered ,increment a count in CL.
This will give the quotient .

x86 Chapter 3 26
v) The quotient and remainder are stored in their allocated space in the data
segment .

The SBB instruction can be used in instances when multibyte subtraction is done .For
example ,to subtract two double words or quad words, SBB will have to be used ,just as
ADC is used (Example 3.12)for multibyte addition.

We have seen so far, addition and subtraction operations using numbers in the
hexadecimal (essentially binary) format .But numbers are also represented in other
formats like BCD ,ASCII etc . There are special like instructions like DAA and DAS that
cater to BCD numbers ,and instructions like AAA, AAS etc which cater to ASCII
operations .In chapter 4 , these instructions will be used in arithmetic calculations using
such numbers.

3.4.3 COMPARE INSTRUCTION


CMP –Compare
Usage : CMP destination ,source
This instruction compares the two operands ,causes the conditional flags to be
affected ,but neither the destination nor the source changes . Comparison is done by a
subtraction operation ,and the flags are set/reset according to the result of this .But only
two flags really matter –they are the Zero flag and the Carry flag .

Consider the instruction CMP destination ,source .The condition of the flags will be as
shown in Table 3.5

If CF ZF
destination > source 0 0
destination < source 1 0
destination =source 0 1

Table 3.5 –Flag settings after a compare instruction

It is thus obvious that following up a compare instruction with a JNC/JC or JNZ/JZ will
do the trick .
If the instruction is ,say CMP AL,BL the way to picture it is -
If AL> BL , CF is reset
if AL< BL ,CF is set
if AL= BL , ZF is set.
If two unsigned numbers are to be compared ,it will be clearer if we use JA/JB as the
mnemonic following the compare instruction ,instead of JC or JNC . This will make it
easier to comprehend the meaning of the result of the comparison ,.
If we want to compare AX and BX we could think of it as :
Jump to target if AX is above BX .The instructions to use will be

x86 Chapter 3 27
CMP AX.BX
JA Target
Similarly ,when testing for equality ,we could use JE/LNE instead of JZ/JNZ .Now ,let
us write a few programs illustrating the use of the compare instruction.

Example 3-15
Two unsigned words are stored in the data segment in locations WORD1 and
WORD2 .The program compares the two numbers and displays a message stating which
number is bigger.

.MODEL SMALL
.DATA

WORD1 DW ------- ;store the first number


WORD2 DW ------ ;store the second number
MES1 DB "WORD1 IS BIGGER$" ;first message string
MES2 DB "WORD2 IS BIGGER$" ;second message string
.CODE
.STARTUP

MOV AX,WORD1 ;copy WORD1 to AX


CMP AX,WORD2 ;compare AX with WORD2
JB SECOND ;If AX < WORD2 ,go to SECOND
LEA DX,MES1 ;point DX to MES1
JMP DISP ;jump to DISP
SECOND: LEA DX,MES2 ;point DX to MES2
DISP: MOV AH,09 ;AH=09 for string display
INT 21H ;DOS function INT21H is called
.EXIT
END

This is a very simple program in which the WORD1 is brought into AX .It is then
compared with WORD2 . The jump (JB) instruction following the comparison, directs
control to the appropriate message . Recall that DOS function call with AH=09 will
display a string on the console.
Note : To run this program , actual data will have to be written in the data segment at
locations WORD1 and WORD2

Example 3.16 finds the biggest of 10 bytes stored in memory ..


Example 3.16

.MODEL SMALL
.DATA

NUMS DB 56H,38H,09H,98H,99H,0C7H,07H,0BCH,0CH,0ECH
BIGGEST DB ? ;store the biggest number
.CODE
.STARTUP

LEA BX,NUMS ;BX is the pointer to the array


MOV CL,0AH ;CL acts as the counter
MOV AL,0 ;AL=0

x86 Chapter 3 28
REPEA: CMP AL,[BX] ;compare each number with AL
JAE AGAIN ;if AL is above or equal, jump
MOV AL,[BX] ;if below, bigger no. to be in AL
AGAIN: INC BX ;increment pointer
DEC CL ;decrement counter
JNZ REPEA ;repeat the sequence if count!=0
MOV BIGGEST,AL ; the biggest number will be in AL
;store it in the location BIGGEST
.EXIT
END

The logic of this program is as follows .


i) The numbers are stored as an array in memory named NUMS . BX is used as
a pointer to this array.
ii) CL contains the count of the numbers(here CL=0AH)
iii) Initially AL = 0.
iv) AL is compared with each number . If AL is not above or equal to the
number in the array , the bigger number is brought to AL.
v) If AL is above the number in the array ,the content of AL is retained as it is.
vi) This is one round of comparison. Then the pointer (BX) is incremented and
count (CL) is decremented.
vii) When the count reaches zero ,ZF is set and the looping is terminated because
of using the JNZ mnemonic.
viii) The biggest number is now in AL which is stored in memory in the space
allocated for it

Example 3.17 is another an interesting program ,which searches a character string for
the presence of a particular character ,and displays appropriate messages.
Example 3-17

.MODEL SMALL
.DATA
STRIN DB "HOWAREYOUMYBOY" ;string of characters
LEN DW 0EH
MESG1 DB 0AH,0DH,"CHARACTER FOUND$"
MESG2 DB 0AH,0DH,"CHARACTER NOT FOUND$"

.CODE
.STARTUP
LEA BX,STRIN ;BX to point to the string
MOV CX,LEN ;copy the string length to CX

MOV AH,01 ; DOS function call for


INT 21H ;character input with echo
;the entered character is in AL
REPEA: CMP [BX],AL ; compare AL with string bytes
JE FOUND ;if equality is found , display
;appropriate message
INC BX ; point to the next byte in array
LOOP REPEA ;if count is not 0,repeat
LEA DX,MESG2 ; character not found ,go to MESG2
JMP DISP

x86 Chapter 3 29
FOUND: LEA DX,MESG1 ;display MESG1
DISP: MOV AH,09 ;DOS function call for display
INT 21H ;of string

.EXIT
END

A character string is a stored in location labeled STRIN .The length of this string is
specified in a word location named LEN . The character whose presence (or absence) we
want to check for , is entered through the keyboard using the DOS function call with
AH=01 . This character is compared with each of the characters in the string .Once
equality is found ,the comparing loop is exited and MES1 is displayed . Otherwise
MES2 is displayed ,after all the characters in the array have been compared .
Note that both the messages (MESG1 and MESG2) are preceded by the newline (0AH )
and carriage return (0DH )characters .This is to ensure that the display is obtained in a
different line ,after the input character (i.e. the one that is entered through the keyboard)
is echoed on the screen.

3.4.4 UNSIGNED MULTIPLICATION


MUL -Multiply
Usage :MUL source
This instruction multiplies a number in AL or AX by the source (where the source can be
a register or a memory location ,but not an immediate number).
All the conditional flags are affected ,but only the CF and ZF are defined as meaningful
for the result. The destination depends on the size of the operand.
There are two ways of performing multiplication .
i) Byte by byte
In this ,one of the operands must be in the AL register ,and the source can be a byte in
a register or memory location. The product (a word) will be in AX .
For example
MUL BL ;multiply BL by AL –product in AX
MUL BYTE PTR[SI] ;multiply the byte pointed by SI, by AL –product in AX
MUL BIG ;multiply the content of BIG by AL –product in AX

ii) Word by word


In this ,one of the operands must be in the AX register ,and the source can be a word
in a register or memory location. The product will be in DX and AX ,with the upper word
in DX.
For example
MUL CX ;multiply CX by AX –product in DX and AX
MUL WORD PTR [DI] ;multiply the word pointed by DI with AX –
;product in DX and AX
Word by byte multiplication

x86 Chapter 3 30
This is only a special case of the word x word multiplication .The byte must be extended
to be a word .by making the upper byte to be 0. If the byte is in AL ,extend it to be a word
by making the content of AH to be zero. Thus AX now contains one of the operands.

Flags Affected
For the multiply instruction ,all conditional flags are affected ,but only the carry (CF)
and overflow(OF) flags have any significance . They will be set or reset according to the
size of the product .Recall that a byte x byte multiplication can produce a result of a word
size .But if the operands are small, the product itself is only a byte, and needs only the
AL register for the product. .In that case ,both the carry and overflow flags are found
cleared ,but if the product occupies a word size ,both these flags are set (CF=1,OF=1).
This concept can be extended to the word x word multiplication as well .We can
summarize that if the product has a size equal to the size of the operands ,both these flags
are reset .i.e. CF=0,OF=0 .However ,if the product is large enough to occupy the registers
assigned for it, these flags are set i.e. CF=1,ZF=1. See this multiplication.
MOV AL 78H
MOV CL ,0F9H
MUL CL

This program segment will cause the product to be 74B8H .Thus the result of the
multiplication is AX =74B8H ,CF =1 and OF=1.

However if the program segment is


MOV AL,13H
MOV CL ,09H
MUL CL
The result is AX=00ABH ,CF=0 and OF=0 .

In example 3-18, two bytes stored in the data segment are multiplied .The result of
multiplication is available in AX ,which is then moved to the location PROD , a word
location .
Example 3.18

.MODEL SMALL
.DATA
MULT DB 0AH ;multiplier
MULP DB 0F6H ;multiplicand
PROD DW ? ;space allocated for product
.CODE
.STARTUP
MOV AL,MULP ;move the multiplicand to AL
MUL MULT ;multiply with the multiplicand
MOV PROD,AX ;product moved from AX to memory
.EXIT
END

Now let use the multiply instruction in a more complex application


Example 3.19 is a program to find the factorial of a number N.

x86 Chapter 3 31
For 8086 , the maximum size of an operand for multiplication ,is only a word .This places
a limitation on the value of N that can be used . It can be verified that N has to less than
9 ,for the program to give the correct result. In this program ,the value of N should be
entered from the keyboard ,remembering that N is to be less than 9. Since any value that
is entered from the keyboard is in ASCII form ,30H is subtracted from it ,to get the
binary value of N to be used in the computation.

Example 3-19

.MODEL SMALL
.DATA
FACT DW 0 ;space allocated for the factorial
.CODE
.STARTUP
MOV AH,01
INT 21H ;enter N from the keyboard
SUB AL,30H ;convert ASCII to binary
MOV AH,0 ;convert N in AL to a word in AX
MOV BX,AX ;move it to BX
MOV AX,1 ;AX=1 ,to start the iteration
CMP BX,0 ;compare BX (=N)to 0
JZ FINAL ;if N=0 ,jump to find 0!
REPEA: MUL BX ;for N not 0, multiply with AX
DEC BX ;decrement BX
CMP BX,0 ;compare with 0
JNE REPEA ;repeat if BX is not 0
FINAL: MOV FACT,AX ; AX=1 ,hence 0!=1
.EXIT
END

The computation is done iteratively . First AX =1 .The value of N is copied to BX .For


N=0 , the factorial is 1 .For this case ,the content of AX is transferred to the location
FACT and corresponds to 0!..If N is not zero ,then it is multiplied with AX. BX is
decremented and cumulatively multiplied with the product in AX. .As N becomes
higher , N! increases steeply ,and only for numbers upto 8 ,will the factorial fit into a
word location .Further multiplication becomes impossible because one of the operands
has a size greater than a word. The value of N! is finally stored in the memory location
labeled FACT.

3.4.5 UNSIGNED DIVISION


DIV -Divide
Usage: DIV source
This instruction divides AX or DX –AX by the source ,where the source can be a register
or a memory location ,but not an immediate number. All the conditional flags are
affected ,but undefined –hence they don’t give any interpretation or information about
the result.
The destination depends on the size of the operand .There are two ways of performing
division

x86 Chapter 3 32
i) Divide a word by a byte .
Here ,the dividend must be a word placed in AX and the source must be a byte . The
result of division causes AL to contain the quotient ,and AH to contain the remainder.
Example
DIV BL ;divide AX by the byte in BL
DIV BYTE PTR [BX] ; divide the word in AX by the byte pointed by BX
DIV DIG ; divide the word in AX by the byte in DIG

See this division


MOV AX, 0C678H
MOV CL ,0F9H
This program segment will cause AH (remainder) =0CH and AL (quotient) = CCH
Dividing a byte by a byte
This is just a special case of a division of a word by a byte.
In this case ,convert the dividend byte to a word by loading the dividend in AL and 0 in
AH .Thus AX will be the word that acts as the dividend.

ii)Divide a double word by a word.


In this case ,the dividend has to be in AX and DX (the upper word in DX).
The divisor should be a word . The result of this division causes the quotient to be in AX
and the remainder to be in DX.
Examples
DIV BX ;divide the dword in DX-AX by the word in BX
DIV WORD PTR [SI] ;divide the dword in DX-AX by the word pointed
;by SI
DIV ANGLE ; divide the dword in DX-AX by the word in ANGLE
Dividing a word by a word
Similar to the previous case ,if we want a word by word division ,extend the word in AX
to be a double word by loading 0 in DX to get the dividend to be a double word in AX
and DX.

Divide by Zero Error

For division ,if the divisor is zero ,the quotient becomes undefined In attempting such a
division ,the 8086 will exit from this program and generate an interrupt .This state is said
to a ‘divide by zero error ‘.An interrupt generated by an error ,is also termed as an
exception. But division by zero is not the only condition to cause such an error . If the
quotient register is too small to accommodate the quotient ,then also this happens .For
example ,if the dividend is a large number and the divisor is very small ,such a condition
is possible .
MOV AX,09876H
MOV CL,25H
DIV CL
The above program segment will give a quotient of 41E H ,which obviously cannot
be accommodated in AL . If this problem had been foreseen , the solution would be to
convert the dividend to a double word, and the divisor to a word. .Then the quotient will

x86 Chapter 3 33
be in AX ,which will be big enough for it ..When such an error occurs ,program
execution is aborted and the assembler displays the message ‘divide overflow error’.
EXAMPLE 3-20
.MODEL SMALL
.DATA
FIRST DB 89H
SECOND DB 0CAH
AVG DB ?
.CODE
.STARTUP
MOV AL,FIRST ;copy FIRST to AL
MOV AH,0 ;zero-extend
MOV BL,SECOND ;copy SECOND to BL
MOV BH,0 ;zero-extend
ADD AX,BX ;add the zero extended words
MOV CL,02 ;load divisor to CL
DIV CL ;divide AX by CL
MOV AVG,AL ;save quotient to AVG
.EXIT
END

Example 3-20 gives a complete program for finding the average of two bytes stored in
memory locations labeled FIRST and SECOND .These are copied to registers AL and BL
and zero extended to convert them to words. Addition of the numbers is then done as
words. This sum ,which is the dividend is in the AX register. The divisor 2 is copied to
the CL register. After division ,the quotient is available in AL and the remainder in AH
.For this problem ,only the quotient is important ,and this is saved to location AVG.

Now we will see a very useful and interesting application of the division operation.
This program converts a 16 bit hexadecimal number to decimal and displays the decimal
number on the console after converting it to ASCII form.
To see the logic of this program ,let us take a number ,say ,246 .
i) Divide this by 10 to get a quotient of 24 and a remainder of 6 .Push
the remainder on to the stack .
ii) Next ,divide the quotient again by 10 to get 2 as the quotient and 4 as
remainder .Push this remainder also on to the stack.
iii) One more division causes the quotient to be zero .This is the stopping
condition in the division loop..
iv) The number of division operations done is counted along with all these
steps. Now pop out the remainders from the stack .This will be in the
reverse order of the push operations .Thus 2 will be popped out first
and 6 last .This can be displayed in this order.
v) For displaying ,each digit must be converted to its corresponding
ASCII .This is done by adding 30H to each digit .

Now ,examine Example 3.21 the program that does the conversion of any 16 bit
hexadecimal number to decimal and then displays it. Here, the hexadecimal ,the number

x86 Chapter 3 34
is placed in the data segment. Note that the division here is accomplished as a double
word by word division.

Example 3.21
.MODEL SMALL
.DATA
NUM DW 0CEF6H ;the hexadecimal number
COUNT DB 0 ;count of the number of divisions done
.CODE
.STARTUP

MOV AX,NUM ;get the hex number into AX


MOV DX,0 ;DX=0 ,thus DX-AX is the dividend
MOV CX ,10 ; the divisor 10 is loaded into CX
REPEA: DIV CX ; divide by CX
PUSH DX ;the remainder in DX is pushed to stack
MOV DX,0 ;DX=0 again to get the dividend in DX-AX
INC COUNT ;increment the count
CMP AX,0 ;check if the quotient (in AL) is zero
JNE REPEA ;if AL is not zero ,repeat the division

DISP: POP DX ;pop out the remainders for displaying


ADD DL,30H ;add 30H to convert to ASCII
MOV AH,02 ;DOS function call for displaying
INT 21H ;a character
DEC COUNT ;decrement the count
JNZ DISP ;if count=0 ,it means all remainders
;have been popped out
.EXIT
END
3.5 LOGICAL INSTRUCTIONS
Table 3.6 gives the complete list of logical instructions and the function performed

Instruction format Function Performed Flags affected


1 AND dest,src Logical AND of the two operands CF OF PF SF ZF
returning the result in the destination (AF undefined)
2 OR dest,src Logical inclusive OR of the two CF OF PF SF ZF
operands returning the result in the (AF undefined)
destination
3 XOR dest ,src Performs a bitwise exclusive OR of the CF OF PF SF ZF
operands returning the result in the (AF undefined)
destination
4 NOT dest Inverts the bits of the "dest" operand None
forming the one’s complement.
5 TEST dest,src Performs a logical AND of the two CF OF PF SF ZF
operands updating the flags register (AF undefined)
without saving the result.

Table 3.6 : List of Logical instructions and functions performed by them

x86 Chapter 3 35
Example 3-22
Find the result and the state of the FLAGS CF,ZF and OF due to the following
instructions.
Given AX =008CH ,BX =345EH , CX=67EBH
II) AND BL,CL
III) OR AH,BH
IV) XOR AL,CH
V) TEST AH,BL

Solution:
i) AND BL,AL

BL= 5E H 0101 1110


CL= EB H 1110 1011
4A H 0100 1010

After this operation , BL contains 4AH . CF=0,OF=0,ZF=0

ii) OR AH,BH
AH = 00 0000 0000
BH = 34H 0011 0100
34H 0011 0100

After this operation , AH=34H .CF=0,OF=0,ZF=0

iii) XOR AL,CH


AL = 8C H 1000 1100
CH = 67 H 0110 0111
EBH 1110 1011

After this operation, AL=EBH, CF=0,OF=0,ZF=0

i) TEST AH,BL
AH = 00 0000 0000
BL = 5EH 0101 1110

After this operation ,the ZF =1 ,OF=0,CF=0

MASKING
There is a word ‘masking ‘ associated with the AND operation .Masking is used to select
the part of a word or a byte needed ,while making the unwanted bits to be zero
For example ,observe the value in AL after the following instructions are executed.
MOV AL, 78 H
AND AL ,0F H

x86 Chapter 3 36
This gives AL=07H in the AL register .The upper nibble of 78 H has been masked.
As another example ,see below where 16 bit data is ANDed with 0FFFH ,so as to mask
the upper 4 bits., This is a particular case when only 12 bits of this data are needed .

MOV AX, ,9876H


AND AX,0FFFH
AX now has a content of 0876H

TYPICAL APPLICATIONS OF LOGICAL INSTRUCTIONS


Now ,let us use these logical instructions in some simple applications

AND
To convert an ASCII number to a binary number ,mask the number with 0FH
MOV AH,01 ;get in the number through the keyboard
INT 21H
AND AL,0FH ;mask the upper nibble
OR
To convert an 8 bit binary number (from 0 to 9) to ASCII , OR it with 30H
MOV AL ,9
OR AL,30H
XOR
To clear a register ,use XOR
XOR BL,BL

TEST
To test whether a bit is set or not use the TEST instruction .
TEST BL,01H
This tests whether bit D0 of BL is 1 or not .If the bit under test is reset ,the AND
operation corresponding to the TEST operations causes ZF to be set.(ZF=1)
TEST CX,8000H
This tests whether D15 of CX is set or not .

3.5 SHIFT AND ROTATE INSTRUCTIONS

Sl Instruction format Function Performed Flags affected


No
1 SHL dest ,count Shift Logical Left by ‘count ‘ bits CF OF PF SF ZF (AF
undefined)
2 SAL dest,count Shift Arithmetic Left by ‘count’ bits CF OF PF SF ZF (AF
undefined)

x86 Chapter 3 37
3 SHR dest,count Shift logical right by ‘count’ bits.
CF OF PF SF ZF (AF
undefined)
4 SAR dest,count Shift Arithmetic Right by ‘count’ CF OF PF SF ZF (AF
bits undefined)
5 RCL dest,count Rotate Through Carry Left by CF OF
‘count’ bits.
6 RCR dest,count Rotate Through Carry Right by CF OF
‘count’ bits
7 ROL dest,count Rotate Left by ‘count’ bits CF OF
8 ROR dest,count Rotate Right. By ‘count’ bits CF OF

Table 3.7 List of the shift and rotate instructions .

3.5.1 SHIFT
i) Shift instructions do arithmetic or logical shifting
ii) They also shift right or left .
iii)Arithmetic shift is used for signed number operations ,while logical shift caters
to unsigned numbers.
iv)Shifting right causes a divide by 2 ,for each bit position shifted, while shifting
left corresponds to a multiplication by 2.
v)The count means the number of bit positions ,by which shifting is to be done.
vi)If the count >1, load it in CL ,otherwise use ‘1’ in the immediate mode.

1)SAL/SHL -Shift left Arithmetic/Shift left logical


Usage: SAL/SHL dest,count
This instruction Shifts the destination left by "count" bits and zeroes are shifted in to fill
the vacant positions on the right. The Carry Flag contains the last bit shifted out. .Because
a ‘0’ is shifted in from the right side .Left shift ‘logical’ and ‘arithmetic’ perform the
same operation and hence the mnemonic SAL or SHL can be used interchangeably
Modifies Flags: CF OF PF SF ZF (AF undefined)

Examples

SHL BX,1 ;shift left logical by one position ,the word in BX


SAL AL,CL ;shift left arithmetic AL by the count specified in CL
SHL DATA2 ,CL ;;shift left logical the content of memory DATA2
; by the count specified in CL
SHL BYTE PTR [BX][DI] ,1 ;shift left (logical)once ,the byte with EA=BX+DI
SAL WORD PTR [DI],CL ;shift left (arithmetic)the word pointed by DI ,by the

x86 Chapter 3 38
;count specified in CL

Example 3-23shows a program segment for finding the weight of the modulo-2 sum of
two numbers.. Modulo-2 sum essentially is finding the positions in which the two
numbers are different – which is an XOR operation. The weight of a number is the
number of 1s in it .
In this problem , the modulo-2 sum is found by XORing the two numbers in AL and BL.
The result of this is then shifted left .The bit shifted out will be in the carry flag On
checking the carry bit ,if it is found to be 1, the register CH is incremented .Along with
this ,the register CL is decremented .CL contains the length of the operand . Here CL=8.
At the end of the program ,we get the ‘weight’ of the modulo-2 sum of AL and BL in
CH. For the numbers used in this program ,CH=6 is the result.

Example 3.23
.MODEL TINY
.CODE
.STARTUP
MOV AL,89H ;move first number to AL
MOV BL,0F7H ;move second number to BL
XOR AL,BL ;EX-OR the two numbers
MOV CL,8 ;CL=8
BACK: SHL AL,1 ;shift left AL once
JNC REPEA ;repeat if there is no carry
INC CH ;increment CH if there is a carry
REPEA: DEC CL ;decrement count
JNZ BACK ;repeat the shifting until CL=0
.EXIT
END

2) SHR –shift right logical


Usage:SHR dest,count
This instruction shifts the destination right by ‘count’ bits and fills with zeroes the vacant
positions on the left. The Carry Flag contains the last bit shifted out.
Modifies Flags: CF OF PF SF ZF (AF undefined)

x86 Chapter 3 39
Examples

SHR DX,1 ;shift right by one position ,the word in DX


SHR WORD PTR [SI]THERE ,CL ;shift right the word with EA=THERE+SI ,by
;the count specified in CL
SHR CH ,CL ;shift right the content of CH ,by the count in CL
SHR BYTE PTR [BP]ISI] ,1 ;shift right by one the byte pointed by EA=BP+SI

Example 3.24 shows an example of a shift operation. When a decimal number is


represented as a 4 bit binary nibble ,and these nibbles are packed in a byte ,it is called
packed BCD representation for example the packed BCD representation of 56 is 0101
0110 . Unpacking it means separating it as two bytes 0000 0101 and 0000 0110.

Example 3.24
Convert a packed BCD byte to two unpacked bytes.
Solution:

.MODEL TINY
.CODE
.STARTUP

MOV AL,95H ;copy the packed BCD byte to AL


MOV BL,AL ;copy the same byte to BL
AND AL,0FH ;mask the upper nibble of AL
AND BL,0F0H ;mask the lower nibble of BL
MOV CL,04 ;move a count of 4 into CL
SHR BL,CL ;shift BL right 4 times

.EXIT
END

In this problem, a packed BCD byte is in AL.


It is to be unpacked and placed in two registers. The operand is AL .Keep a copy of it in
BL too . For unpacking ,fist the upper nibble of AL is masked . This gives one unpacked
BCD byte. This is now in AL Next ,the lower nibble of BL is masked ,and the result is
shifted right 4 times to bring the upper nibble data to the lower nibble position.
Now ,the two unpacked bytes are available in AL and BL.

Note : The operation and practical use of the SAR instruction will be discussed in
Chapter 4 ,where signed number arithmetic is dealt with .

x86 Chapter 3 40
3.5.2 ROTATE INSTRUCTIONS
Rotate instructions have the same format as the shift instructions .There are two types of
rotate – rotate through carry or without taking the carry bit as a part of the rotate act.

ROL – Rotate Left


Usage: ROL dest, count
This instruction rotates the bits in the destination to the left "count" times with all data
pushed out at the left re-entering on the right. The Carry Flag will contain the value of
the last bit rotated out.
Modifies Flags: CF OF

Examples
ROL SI, CL ;rotate left the word in SI ,by the count in CL
ROL BYTE PTR [DI][BX],1 ;rotate left the byte pointed by EA=[DI+BX] once

ROR - Rotate Right


Usage: ROR dest,count

This instruction rotates the bits in the destination to the right ‘count’ times with all data
pushed out at the right side re-entering on the left. The Carry Flag will contain the value
of the last bit rotated out.
Modifies Flags: CF OF
Examples
ROR AL,1 ;rotate right once the byte in AL
ROR DX,CL ;rotate right the word in DX the count in CL
Let us examine what Example 3.25 will do.
Example 3-25

.MODEL TINY
.CODE
.STARTUP
MOV BX,5634H
MOV CL,8
ROL BX,CL

x86 Chapter 3 41
MOV AL,0C6H
MOV CL,4
ROR AL,CL
.EXIT
END

In the first instance ,there is a 16 bit register BX which contains the value 5634H..By
using ROL ,and rotating 8 times the value in BX changes to 3456H. .Similarly with
AL=C6H , using ROR with a count of 4 ,Al will have the new value of 6C H. Thus we
can switch exchange nibbles or bytes using the rotate instructions with the appropriate
count in CL . Note that ,for this application ,it does not matter if ROL or ROR is used.

It is easy to check that Example 3-24 can be re-written replacing the SHR instruction
with either the ROL or ROR instruction.

RCL - Rotate Through Carry Left


Usage: RCL dest, count
This instructions causes the left most bit (LSB) to enter the carry flag ,and the CF enters
through the left end(MSB) Thus ,due to one shift operation ,the MSB enters the CF ,and
the CF gets into the LSB position.
Modifies Flags: CF OF

Examples
RCL BL,CL ; rotate left through carry , BL ,by the count in CL
RCL CX,1 ; rotate left through carry the word in CX once

RCR - Rotate Through Carry Right


Usage: RCR dest, count

x86 Chapter 3 42
This instructions causes the right most bit (MSB) to enter the carry flag ,and the CF
enters through the left end(MSB) Thus ,due to one shift operation ,the LSB enters the CF
,and the CF gets into the MSB position.
Modifies Flags: CF OF
Examples

RCR BYTE PTR [SI] ,1 ;rotate right through carry ,the byte pointed by SI,once
RCR WORD PTR [DI][BX],CL ;rotate right through carry the word pointed by
EA=SI+BX ,by the count specified in CL

Example 3.26

Find the values in the destination for each line of this program segment.
STC
MOV AX,5485H
RCR AL,1
MOV CL,03
RCL AX,CL
MOV CL,05
ROR AX,CL
ROL AX,1
Solution:

Instructions Result after execution

STC CF=1
MOV AX,5485H AX=0101 0100 1000 0101
RCR AL,1 AL=1100 0010
MOV AL,03 CL=03
RCL AX,CL AX=1010 0110 0001 0101
MOV CL,05 CL=5
ROR AX,CL AX=1010 1101 0011 0000
ROL AX,1 AX=0101 1010 0110 0001

Key Points of this chapter

 BIOS and DOS function calls facilitate the use of input and output devices in
programming, making it interactive and more fun.
 The instruction set of 8086 can be divided into groups based on functionality.
 MOV is the most frequently used instruction and it is part of the data transfer
group.
 LEA is an instruction that copies the offset of a memory address to a 16 bit
register. It can be used to make the register be a pointer to an array of data items
in memory.
 PUSH and POP can be used only with the stack segment

x86 Chapter 3 43
 The SS register contains the upper 16 bits of the lowest (base) address in the stack
segment. SP contains the offset (with respect to the base address ) of the highest
address in the stack.
 Branch instructions cause the program sequence to change.
 JUMP is an important branch instruction which can be far or near ,and
unconditional or conditional.
 Jumps using the direct mode of addressing are re-locatable and ‘relative’.
 LOOP is a jump instruction which causes branching as well as decrementing a
count in CX. A LOOP instruction can be conditional ,as well.
 There are 20 arithmetic instructions for 8086 ,of which a few specifically cater to
signed numbers, a few to BCD numbers ,and a few to ASCII numbers.
 The ADC(Add with carry) and SBB (Subtract with borrow) instructions find use
in multibyte additions and subtractions.
 The INC and DEC instructions do not affect the carry flag.
 The CMP (Compare) instruction subtracts the source from the destination
and sets/resets flags ,but neither the source nor the destination is altered.
 MUL is the mnemonic for unsigned multiplication .For a byte by byte
multiplication ,one operand is implied to be in AL and the product in AX. For a
word by word multiplication , one operand is to be in AX and the product will be
in DX-AX.
 DIV is the mnemonic for unsigned division. For a word by byte division ,the
dividend is to be in AX .After division ,the quotient will in AL ,and the remainder
in AH .For a double word by word division ,the dividend is to be in DX-AX
.Then the quotient will be in AX and the remainder in DX.
 If the quotient is too large to fit in the register assigned for it , a ‘divide by zero’
error will be generated.
 The logical instructions of 8086 are AND,OR,XOR,NOT and TEST.
 The TEST instruction does logical ANDing ,but only the flags are affected.
 Shifting of a data can be done left or right ,and also by as many positions as
required.
 Arithmetic shifting is meaningful for signed numbers , while logical shifting
pertains to unsigned arithmetic.
 Rotation can be done left or right and can be direct or through the carry flag.

QUIZ
1. Distinguish between the top-down and bottoms-up approach in programming.
2. What is the use of DOS function calls in assembly programming?
3. How many operands do each of the following instructions have?
a. ADD ii) ADC iii) INC
4. Which conditional flag is not affected by the DEC instruction?
5. If AX=5600H and BX=0C07H ,find the contents of CX and DX after the
following three sets of instructions.
i) PUSH AX ii) PUSH AX iii) PUSH BX
PUSH BX PUSH BX PUSH AX

x86 Chapter 3 44
POP CX POP DX POP CX
POP DX POP CX POP DX
6. Why is the stack pointer called the TOP OF STACK?
7. Distinguish between a near and a far jump.
8. Specify two ways of specifying an unconditional jump in the indirect mode of
addressing.
9. Why does the far jump have five bytes of instruction length?
10. Name a conditional jump instruction that does not test a conditional flag.
11. What are the conditions under which a LOOPZ instruction exits looping?
12. What does the instruction STC do?
13. Can the ADD instruction use CS as a destination?
14. The instruction INC [SI] seems ambiguous .Why? How can the ambiguity be
corrected?
15. What does the instruction CMP AX,BX do?
16. What is the role of OF and CF in multiplication?
17. What happens if the DIV instruction is used for a dividend of 1938H and divisor
of 05?
18. What is meant by masking? Give an example of how it is used?
19. How can multiplication and division be achieved by shift operations?
20. What is the difference between the instructions RCL and ROL?

EXERCISE
1) Write a program to print on two separate lines ,the messages ‘Hi, folks’
and ‘I am Samantha’.
2) Enter a character through the keyboard without echoing it on the video monitor.
Compare it with a number stored in memory and display the message ‘EQUAL’
or ‘NOT EQUAL’ as the case may be.
3) Display each character of the word PRADO on a separate line.
4) Enter ‘N’ characters through the keyboard without echo. Save it in memory as an
array .Then display it as a character string.
5) Indicate what is wrong with each of these instructions.
i. MOV CX,DL
ii. ADD DATA1,0978H
iii. MOV BYTE PTR [SI][BX],DX
iv. MOV 045FH,AX
v. MOV [DX],AL
vi. MOV [SI][CX].AX
vii. MOV DS,3453H
6) Write a program that adds two quad words and stores the result in memory.
7) Write a program that subtracts two double words and stores the result in memory.
8) Find the status of the CF and ZF flags after the execution of the following sets of
instructions.
i) MOV AX,9078H
CMP AX,0C089H
ii) XOR AL,AL
iii) MOV AL,29H

x86 Chapter 3 45
CMP AL,0
9) Find the biggest number in an array of i) bytes ii) words. Display the biggest
number in each case ,as a decimal number.
10) There are 10 unsigned bytes stored in memory .Arrange these bytes in i)
ascending and ii) descending order.
11) Find the average of 20 bytes stored in memory .Display the average as a decimal
number.
12) Add the sum of the first 20 natural numbers .Display the sum.
13) Write a program that counts the number of 1s in a binary number.
14) Write a program to add two N x N matrices.
15) Find the number of times a particular character is present in a character string
stored in memory.

x86 Chapter 3 46

You might also like