You are on page 1of 22

1

UNIT 3 ASSEMBLY LANGUAGE PROGRAMMING (PART -I)


3.0 Introduction
3.1 Objectives 3.2 Simple Assembly Programs 3.2.1 Data Transfer 3.2.2 Simple Arithmetic 3.2.3 Shift Operations f 3.2.4 Larger O The Two Numbers 3.3 Programming With Loops and Comparisons 3.3.1 Simple Program Loops 3.3.2 Find The Largest And The Smallest Array Values 3.3.3 Character Coded Data 3.3.4 Code Conversion 3.4 Programming for Arithmetic and String Operations 3.4.1 String Processing 3.4.2 Arithmetic Problems 3.5 Summary 3.6 Model Answers

1
I

Structure

i
b

3.1

INTRODUCTION

After discussing about few essential directives, program developmental tools and simple programs, let us discuss more about assembly language programs. In this unit, we will start our discussions with simple assembly programs which fullils simple task such as data transfer, arithmetic operations, shift operations. A kcy example here will be about finding larger of two numbers. T b r e a f ~ e rwe will , discuss about more complex programs showing how loops and various comparisons are used to implement tasks like code conversion, coding characters, finding largcs~ in array etc. Finally, we will discuss about more complex arithmetic and string operations. You must refer to further reading for more discussions on these programming concepts.

3.1

OBJECTIVES

At the end of this unit, you should be able to: write assembly programs with simple arithmetic logical and shift operations implement loops use comparisons for implementing various comparison function write simple assembly program for code conversion a write simple assembly program for implementing arrays

3.2

SIMPLE ASSEMBLY PROGRAMS

As part of this unit, we will discuss to write assembly language programs. We shall start with very simple programs, and later graduate to more complex ones.

32.1 Data Transfer


Two most basic data transfer instructions are MOV and'XCHG. Let us consider the following program which'uses both these instructions, to exchange two memory variables.

Microprocessor and Assembly Language Programming

DATA SEGMENT VALUEl DB VALUE2 DB DATA ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA MOV AX, DATA MOV DS, AX MOV AL,VALUEl XCHG VALUE2,AL MOV VALUE1,AL MOV AX,4COOh
; Load Value1 into AL

OAh 14h

;Initialize Variables

; exchange AL with Value2 ;Store Al in Value1


; Halt

INT 21h
CODE ENDS END MOV instruction has already been described in detail in the Unit 1. We shall only revise some of the limitations on types of operands for this type of data transfer instructions:

CS and IP may never be destination operands.

- Immediate data and variables may not be moved to segment registers.


The source and the destination operands may be of the same size. Both these operands cannot be memory locations. destination or 65,535 (FFFFh) for a 16 bit destination. MOV AL,VALUEl

- If the source is immediate data, it must not exceed 255 (FFh) for an &bit

In the above MOV, Valuel is copied into AL:


A AX : 00 O O A 14 (VALUEl) (VALUE2)

XCHG

AL,VALUE2

AL is exchanged with VALUE2 memory variable: AX : 00 14 OA 1(VALUE1) OA (VALUE2) VALUE1,AL

MOV

Moves AL to Valuel, completing the exchange of two variables:

Other statements in the above program have already been discussed in the preceeding units.

3.2.2 Simple Arithmetic


Hardly any computer could avoid performing arithmetic. The Intel instruction set has instructions for integer arithmetic, using &bit and 16-bit operations. Floating point-operations can be handled by the 8087 Math Coprocessor. Example:

Assembly Language Programming (Parl-I)

; ABSTRACT

:This program averages two temperatures


;named HI-TEMP and LO-TEMP and puts the ; result in the memory location AV-TEMP.

; REGISTERS
;PORTS DATA

: Uses DS, CS, AX, BL : None used

SEGMENT DB 92h DB 52h DB


?

HI-TEMP LO-TEMP AV-TEMP DATA CODE

; Max temp storage


; Low temp storage ; Store average here

ENDS S EG M ENT

ASSUME C:S:CODE, DS:DATA START: MOV AX, DATA MOV DS, AX MOV AL, HI-TEMP ADD AL, LO-TEMP MOV AH, ()Oh ADC: AH, ()oh hlOV BL, O3h I>IV [ { I .
; Initialize d a t ; ~ scgrncnt

; rcgi"er

; C;ct first tcrnpcraturc


; Add sccond l o i~
; C'lcar
; Put

all of AH rcgistcr

carry in LSB oTAH

; Load divisor in BL rcgistcr

; Divide AN by BL. Quoricnt in AL, ; and remainder in AH

MOV AV-TEMP, AL CODE END


'

; Copy result to memory

ENDS START

I n the above program, the ADD AL,LO-TEMP i~islruction adds the specified byte from memory to the contents of thc AL register. I t is not possible to directly add the contents of two memory locations, thercforc,HI-TEMP was first moved into a register.

Thc ADC AH,OOh instruction adds the immediate number OClh plus the contents of the carry flag to the contents of the AH register. The result will be left in the AH rcgistcr. Since we had cleared AH to all zeros, before the add, what we are really adding is O h + O h + CF. The result of all this is that the carry flag bit is put in O O the AH register.

Micropmessor and Assembly Language Programming

The next major action of our program i~ to divide the $um of two temperature, h> 2 You would remember, in our first unit, we had mentioned two divide instructlon4 DIV and IDIV, for unsigned and signed arithmetic respcctivcly. In our examplc, u.c. have assumed the temperatures to be only positive, and have, therefore, ured unsigned division instruction. In a more general case, we could have assumed the temperature to be both positive and negative, and used IDIV instruction. Before performing the divide operation, thc dividend is put in the AX register and thc divisor in any &bit register. We have used BL register in our case. After the division, the 8-bit quotient will be left in the AL register, which can then be copied into the third memory location.

3.23 Shift Operations


Refer Unit 1in which we have discussed the shift and rotate instructions. They are strongly related to the multiplication and division instructions. As shift and rotates are not generally available in high level languages, so assembly language may be an absolute necessity in certain type of applications. Example: For many applications, we want to convert the ASCII code to its simple BCD equivalent. This can be done by simply replacing the bits in the upper nibble (a nibble = 4 bits) of the byte by four zeros. The number obtained is called unpacked BCD nurnbcr. The upper nibble of these is zero. So the upper nibble can be used to store another unpacked BCD number. The byte thus obtained is called packed BCD number. The algorithm to convert two ASCII codes to packed BCD can be stated as: Convert first ASCII number to unpacked BCD. Convert the second ASCII number to unpacked BCD number Move first BCD nibble to upper nibble position in byte. Pack two BCD nibbles in one byte The assembly language program for the above can he written in the following manner.
;ABSTRACT

;Program produces a packed BCD byte from 2 ASCII; encoded digits. The number is 59.
;The first ASCII digit (5) is loaded in BL.
; The second ASCII digit (9) is loaded in AL.

;The result (packed BCD) is left in AL ;REGISTERS


;Uses CS, AL, BL, CL ; None used

;PORTS CODE

SEGMENT ASSUME CS:CODE

START:

MOV

BL,

'5'

; Load first ASCII digit into BL

MOV AL, AND BL,

'9
OFh

; Load second ASCII digit into AL

;Mask upper 4 bits (nibble) of first ;digit


; Mask upper 4 bits of second digit

AND AL, MOV CL,

OFh
04h

; Load CL for 4 rotares required

ROIC)R

BI..
tZ I..

C 1.
RL.

; Rotate

BL 4 bit positions

A~stmbly Language Proprammlq (Part-I)

; Combine

nihhlcs, result in AL contains 59 : as packed BCD

CODE

ENDS

END

START

You would find in the aho\.c csamplc. that we are using ROL and OR instructions.
8086 docs not ha\v any instruction to swap two nibbles in a byte, it can however exchange two hytcs or words using XCHG instruction. Out of the two rotate

i
b

instructions, ROL ancl RCYL. we ha\x chosen ROL, for the following rcason. ROL rotates Icft the byte Icft by one or more positions, bringing the MSB into LSB position and also mo\.ing it into thc carry bit. RCL on thc other hand, moves thc MSB into the carry l1;1gand brings the original carry flag inln the LSB position. Lvhich is not whirl we want. By using ROL four times we can mo\:c thc upper nibblc into thc Iowcr nil>hlc position, and the lower nithle into the upper one. Lct us now look at irn csiini~lc using RCL instruction. This will makc the differcncc hct\vccn the instrurtion~ clcirr. The folio\\-ing program adds a hytc numhcr from one mcmory location to a byte I'roni thc ncst memory location. puts the sum in the third mcmory location. and ~ i v the %talcof the carry flag in ~ h least significant bit of the fourth mcmory c c location. The upper 7 141sof the memory location where the carry is storcd arc n~;r\L;ccl. :ABSTRACT
: -This program adds 2 8-hit words in the memory locations

: called SUM1 and SL'M9,. The rcsult is storcd in


: thc memory location cirllcd RESULT. I f thcrc

: wa\

3 carry

from the addition then it will he

: storcd from the addition it will be stored as

: O O 0001 in thc location CARRY oO

; ALCiORITHM:

gct NUMl add NUM2 put sum into memory at SUM

,
r
,

position carry in LSB of byte mask off upper seven bits store the result in the carry location.

; PORTS

: None used

; PROCEDURES
; REGISTERS

: None used
: Uses CS, DS, AX

Mlcroprwcssor and Asstmbly Imwusgr Programming

; DATA

SEGMENT DB DB 15h 20h


?
?

NUMl NUM2

; First number stored here


; Second number stored here ; Put sum here ; Put any carry here

RESULT DB CARRY DB DATA CODE ENDS

SEGMENT

ASSUME CS:CODE, DS:DATA START:MOV AX, DATA MOV DS, AX MOV AL, NUMl ADD AL, NUM2 MOV RESULT, AL RCL AL, 01 AND AL, O O O OB OOOl MOV CARRY, AL CODE END ENDS START
; Initialize data segment

;register
;Get the first number

;Add it to 2nd number

;Store the result


; Rotate carry into LSB ; Mask out all but LSB
;Store the carry result

RCL instruction brings the carry into the least significant bit position of the AL register, and the AND instruction masks all the higher bits. (Please compare it with how carry was brought in AH register in the example in section 3.2.2) In a similar manner we can also write applications using other shift instructions.

3.2.4 Larger Of The Two Numbers


The algorithm for comparing two numbers is: Let there be two numbers A and B. If A is greater than B, then A is larger else B is larger. This tells us that we should have some comparative instructions in the assembly language, through which we can compare two numbers. As you would recall from our discussion of the first unit, CMP instruction offers a convenient way of comparing two &bits or 16-bits operands. The result is reflected in the flags register. Generally only three flags are important as shown in the following table:

Result of comparison
Destination < source Destination = source Destination > source

Flag(s) affected
Carry flag = 1 Zero flag
=

Carry = 0, Zero = 0

Let's look at three examples that show how the flags are set when the numbers are compared. In example 1AL is less than 10, so the carry flag is set. In example 2, the, zero flag is set because both the operands are equal. In example 3, the destination (SI) is greater than the source, so both the zero and the carry flags are clcar.

Example 1. MOV AL, 05 CMP AL, 10 Example 2. MOV AX, 1000 MOV CX, 1000 CMP AX,CX Example 3. MOV SI, 105 CMP SI, 0
; Zero and Carry flags = 0 ;Zero flag = 1
; Carry flag = 1

Assembly language Programming (Yarl-I)

We shall do a more complete example in the following sections whcrc wc shall scc how to make actual use of these instructions.

Check Your Progress 1


State true or rake with respect to 8086/8088 assembly language: 1. In a MOV instruction, the immediate operand value for 8 bit destination can not exceed FOh. True 2.

I[

False

1-1

XCHG VALUE1, VALUE2 is a valid instruction.


True False

3.

In the example given in section 3.2.2 we can change instruction DIV BL with a shift. True ~alse

4.

A single instruction can not swap two nibbles of a byte register. True False

5.

An unpacked BCD number require 8 bits for storage, however, two unpacked BCD numbers can be packed in a single byle register. True False

6.

If AL = 05 andBL = 06 then CMP AL, BL instruclion will clear the zero and carry flags. True

False

Mkroproccssor and Assembly


L.~P~P pmsnmmlag

33

PROGRAMMING WITH LOOPS A N D COMPARISONS

let us now discuss few examples which are slightly more advanced than what wc have been doing till now. This section deals with more practical examples using loops, comparison and shift instructions.

33.1 Simple Program Loops


The loops in assembly, can be implemented using unconditional jumps (JMP) conditional jumps (JC, JNC, JZ, JNZ etc.), and LOOP instructions. All these instructions have already been discussed in the earlier units. These together can be used to get practically any type of loops possible in high level language. Let us consider some of the examples, explaining the use of conditional jumps. Example: CMP JE ADD THERE: MOV AX,BX THERE AX, 02 CL, 07
;compare to set flags ;If equal then skip correction
; add correction factor

; load CL with the value 07

In the above example the control of the program will be directly transferred to the label THERE only if AX register is equal to the register BX. The same example can be rewritten in the following manner, using different jumps. Example: CMP JNE JMP FIX: ADD AX,BX FIX THERE AX, 02 CL, 07
;compare to set flags ;if not equal do correction

, ; if equal skip correction


; add correction factor

THERE: MOV

Obviously the above piece of code is inefficient as compared to thc rirst example. .r> there is an additional jump which has occurred due to J N E . Hence care must he taken while picking up the instructions. Example: The following example, adds an inflation factor to a serics of price4 In memory. It copies the new price over the old price. The algorithm for the above can be w r i ~ ~ e nfollows: as Repeat Get a price from the array Add inflation factor ~ d j u iresult to correct BCD t Put result back in array Until all prices are inflated

: RE<;lSTERS: Uses DS, CS, AX, BX, CX : PORTS : None used

ARRAYS

SEGMENT COST DB 20h, 28h, 15h, 26h, 19h, 27h, 16h, 29h 36h, 554 27h, 42h, 38h, 41h, 29h, 39h

PRICES DB ARRAYS CODE ENDS SEGMENT

ASSUME CS:CODE, DS:ARRAYS START: MOV MOV LEA MOV DO-NEXT: MOV ADD DAA MOV INC DEC JNZ CODE ENDS END START [BX], AL BX CX DO-NEXT AX, ARRAYS DS, AX BX, PRICES CX, 0008h AL, [BX] AL,03h
;Initialize data segment
; register ; Initialize pointer ; Initialize counter

;Copy a price to AL ;Add inflation factor


; Make sure result is BCD

;Copy result back to memory


; Point to next price ; Decrement counter

; If not last, go get next

LEA BX,PRICES will load the BX register with the offset of the array PRICES in the data segment. [BX] contains the value stored at thdt element of the array PRICES. BX can be directly incremented to point to the next element of the array. Every time the register BX is incremented, CX register is decremented by one to keep a check of the bounds of the array. Once the CX register becomes /cro, Zero llag is set to 1. Therefore, before going to fetch the next byte from the array PRICES, CX is decremented, and JNZ instruction is used to jump to the start of the loop. The same program can be written using the LOOP instruction, in which case, DEC CX and JNZ DO-NEXT instructions are replaced by LOOP DO-NEXT instruction. LOOP decrements the value of CX and jumps to the given label, only if CX is not equal to zero.

3 3 2 Find The Largest And The Smallest Of The Array .. Values


Let us now put together whatever we have done in the preceeding sections and write down a completc program to find the largest and the smallest numbers from a given array. The program uses the JGE (jump greater than or equal to) instruction, bec;ruse wc have assumcd the array values as signed. JAE instruction works correctly only in thc case of unsigncd numbers. For example, if we used JAE to compare -1 to 0, JAE would treat the numbers as unsigned and consider -1

. Language Programming
/

Mkroproccssor and h m b b

(FFFFW) to be the larger number. JGE on the other hand, would treat the numbers as signed and consider 0 to be greater than -1.
The smallest and the largest variables are first initialized to the first number in the array. They are then compared with the other array values one by one. If the value happens to be smaller than the assumed smallest number or larger than the assumed largest value, the smallest and the largest variables are changed with the new values respectively. DI points to the current array value and LOOP instruction is used to scan the array elements.

CODE

SEGMENT MOV MOV MOV MOV MOV MOV MOV AX,DATA DS,AX DI, OFFSET ARRAY AX, [DI] LARGEST, AX SMALLEST, AX CX,6 AX, [DI] AX, SMALLEST A2 SMALLEST, AX A3
;initialize DS
; DI points to the array ;AX contains the first element

; initialize largest
; initialize smallest

;loop counter ;get array value ; [DI] = smallest?

Al:

MOV CMP JGE MOV JMP

;yes :skip
; no : move [DI] to smallest ;as it is smallest, thus no need ;to compare it with the largest
.

i
I

A2:

CMP JLE MOV

AX,LARGEST A3 LARGEST, AX DI,2 A1 AX, 4C00h 21h

; [DI] = largest

;yes : skip ;no : mov [Dl] to largest


;point to next number ;repeat the loop until CX = 0

A3:

ADD LOOP MOV INT

;halt, return to DOS

CODE DATA

ENDS SEGMENT ARRAY LARGEST SMALLEST DW DW DW -1, 2000, -4000, 32767, 500, 0
?

DATA

ENDS

2 is added to DI to poinl to ncxl elcment of the array, as the array consists of words, whose length is equal to 2 bytes. This program can be made faster if smallest and largest are stored temporarily in registers for comparisons. ,

3 3 3 Character Coded Data


The arithmetic shown so far has dealt with numbers. The CPU calculates in binary. We may however be required to work with characters that are directly inputted from the console or a file. These characters are called as ASCII characters. Suppose we want to input two numbers from the console and add them together. You must have already written such kind of programs in high level language. The following is a sample console session. Enter first number Enter second number The sum is
3402

1256 4658

As each digit is input, we would store its ASCII code in a memory byte. After the first number was input the number would be stored as follows:
33 34
3 4

30
0

32
2

hexadecimal storage ASCII digits

In order to calculate the sum, we have two alternatives, either to convert the ASCII digit string to a 16-bit binary value, which in turn could be used in arithmetic calculations; or we can add the ASCII digits themselves. For the second option there are instructions like AAS (ASCII adjust after subtraction), AAD (ASCII adjust alter division), AAA and AAM available. These can be used dirtctly without much difficulty. Refer unit 1 of this block for details on these instructions:We shall demonstrate the first option in the next section. Another type of coded data available is packed decimal numbers (packed BCD). It contains two decimal digits per byte. You have already been doing a lot of examples of this in the previous units. Packed BCD format has at least three strengths:

* The numbers may have almost any number of significant digits. This makes
possible calculations with a great deal of accuracy.

* Conversion of packed BCD numbers to ASCII (and vice versa) is relatively


fast.

* An implicit decimal point may be used by keeping track of its position in a


scparate variable Two instructions, DAA (decimal adjust after addition) and DAS (decimal adjust after subtraction), adjust the result of an addition or subtraction operation on packed decimal numbers. Unfortunately no such instruction exists for multiplication and division. In those cases, the number must be unpacked, multiplied or divided and packed again. For details of DAA and DAS instructions look back to unit 1.

33.4 Code Conversion


The conversion of data from one type to another might not be avoidable. Therefore, in this section we will discuss an example, where we are converting an ASCII digit to binary form. We will also discuss about conversion of ASCII digit into a 16 bit binary number. Conversion of ASCII number to packed BCD number has already been demonstrated in the previous sections. Example:
;Abstract ;

This program converts an ASCII number into the hex digit

Mkroproccrror and Asslmbly Lmn~uage Prqlmrnmlng

that it represents. To try out the program, the ASCII digit

;
;

is read from a location in memory called ASCII. The hex


result is left in *L. The result in AL is FF if the number is outside the ASCII number or letter limits specified.

;ALGORITHM:
;

I F number < 30h THEN error ELSE IF number < 3Ah THEN Subtract 30h (its a number 0-9) ELSE (number is > 39h) I F number < 41h THEN error (number in range 3Ah -40h) ELSE IF number < 47h THEN Subtract 37h for letter A-F 41-46 ELSE error

;
9

,
J

;PORTS

: None used

;PROCEDURES : None ;REGISTERS


9

: Uses CS, DS, AX,

DATA ASCII DATA CODE

SEGMENT DB 39h ENDS SEGMENT


;experimental data

ASSUME CS:CODE, DS:DATA START: MOV MOV MOV AX,DATA DS,AX AL. ASCII
; Initialize data segment
; register

; <;ct the BCD number

;start the conversion CMP JB CMP JB CMP AL, 30h ERROR AL,3Ah NUMBER AL, 41h ERROR
; If greater then possibly a lettc~
; Is it a letter? ; Between 3A and 40 is error
; Nor

an ASCII 0-9or A-F character

JB

CMP J A. SUB JMP NUMBER: SUB JMP ERROR: MOV

AL, 46h ERROR AL, 37h CONVERTED AL, 30h CONVERTED AL,OFFh
;It's a number so convert

Assembly Language Programming (Parl-I)

; Out of ASCII 0-9, A-F range ;It's a letter so convert

CONVERTED: NOP CODE ENDS END START


;The hex result is in AL

In the above program, we have demonstrated it for a single binary digit represented by and ASCII character. The program can be extended to take more ASCII digirs .tnd convert them into a 16 t i t hinarv numhcr. Thi5 can hc done in rhc follouing m'rnncr: Example: Assume CX contains the hexadecimal number obtained afrer conversion. BX contains 10, AX contains the number obtained till now. To start with A X was equal to 0. Now assume that AX has become 0020h and CL = 02. AND MUL ADD CX, OOOFh BX AX,CX
; convert digit to binary

; DX :AX = AX

* 10

; add new digit to AX

Follow the above steps with the AX and CL values given above. AL is multiplied by BL, so AX = 0140h. CL is added to AX, yielding 142h. You can improve your program by checking for overflow conditions also.

Check Your Progress 2


1

Write the code sequence in assembly for performing following operation:


Z = ((A-B) / 10 * C) ** 2

...................................................................
2.

Write an assembly code sequence for adding an array of binary numbers.

3.

An assembly program is to be written for inputting two 4 digits decimal numbers from console, adding them up and putting back the results. Will you prefer packed BCD addi~ion such numbers? Why? for

Microprocessor and Assembly Language Programming

................................................................... ...................................................................
How can we implement nested loops, for example, for (i = 1to 10, step 1)

{ for (j = 1to 10, step 1)


addltoax) in assembly language?

....................................................................

3.4

PROGRAMMING FOR ARITHMETIC AND STRJNG OPERATIONS

In this section we go a step forward, to look at more advanced features of assembly language programming. These are some of the features that give it an edge over the high level language programming. One of the very important set of instructions is for string processing. If you write the same code in high level language, the object code generated after compiling is much longer than for the same program written in assembly language. In the next section we shall demonstrate this.

3.4.1 String Processing


Write a program in any high level language for comparing two strings. Consider the following piece of code which has been written in some hypothetical high level language, to compare two strings. Let us assume that 'strl' and 'strZ are two strings, initialized by some values, and 'in& is the index for these character strings. Consider the following program:

while (ind < 9) and (strl[ind] = str2[ind]) do ind : = ind

+ 1;

The intermediate code in assembly language generated by the compiler for the above piece would look something like this: MOV IND,00 IND, 08 L1 AX,STRl BX,IND CX,STR2
;ind : = 0 ; ind < 9
;not so; skip

L3: CMP
JG
LEA MOV LEA

;offset of strl in AX register


;it uses a register for indexing intothe array
;str2 in CX

MOV CMP JNE MOV ADD L2: JMP

DL, BYTE PTR CX[BX] DL, BYTE PTR AX[BX] L1 IND,BX IND,01 L3
;strl[ind] = str2[ind] ;no, skip

Assembly Lnngungt Programming (Part-1)

;loop back

You see, there is lot of redundant code, which could have been avoided, if we had written the same program directly in assembly language. The code is further improved if we write it using the string instructions as follows. Example: ;REGISTERS :Uses CS, DS, ES, AX, DX, CX, SI, DI DATA SEGMENT PASSWORD DESTSTR MESSAGE DATA CODE ENDS SEGMENT DB DB DB 'FAILSAFE' 'FEELSAFE'
;source string ;destination string

'String are equal'

ASSUME CS:CODE, DS:DATA, ES:DATA MOV MOV MOV AX,DATA DS,AX ES,AX
;Initialize data segment register
; Initialize extra segment register

;as destination string is considered ; to be in extra segment

I'! I
REPE

LEA LEA MOV CLD

SI, PASSWORD DI, DESTSTR CX, 08

;Load source pointer ;Load destination pointer ;Load counter with string length ;Clear direction flag

CMPSB JNE NOTEQUAL AH,09

;Compare the two string byte ;by byte

;If not equal, jump to ;NOTEQUAL


;else display message

I I I

MOV MOV INT 21h N0TEQUAL:MOV

DX, OFFSET MESSAGE ;


;display the message

AX, 4C00h

;interrupt function to halt

Microprocessor end AEsellrLly L a n g u w Programming

INT CODE ENDS END

21h

In the above program, you would notice, a new instruction CMPSB, compares the two strings, pointed by SI and DI registers, and present in the data and the extra segments respectively. It compares the strings byte by byte and subsequently increments the string pointers by one. The same instruction, but with a 'W' suffur instead of 'B' can be used to compare the strings word by word. The REPE prefix in front of the instruction, tells the 8086 to decrement the CX register by one, and continue to execute the following instruction, until the counter in CX becomes zero. Thus, you should now be able to appreciate, the advantage of using the string instructions in assembly. These considerably reduce the code. We have also introduced a new interrupt function, used for displaying the string message. The string is assumed to be present in the data segment, and the DS register is assumed to contain the offset of the data segment. The function number for displaying the string is stored in the AH register, DX register contains the offsc~ of the string to be displayed. A similar type of the program, as above, can be written to move one string to another, MOVS, and scan a string for a character, SCAS.

Let us now take up some more practical arithmetic problems.


Example 1 Delay Loops

The first problem, which is a very useful application of assembly, is to produce delay loops. Delay loops are used in places, where you are required to wait for some time before executing the next instruction. To do this, let us first discuss about the calculation of the time for the delay. The rate at which the instructions are executed is determined by the clock frequency. Each instruction takes a certain number of clock cycles to execute. This multiplied by the clock frequency of the microprocessor, gives the time in actual, that the instruction takes to execute. For example, MOV instruction takes four clock cycles. When it is executed on a microprocessor of clock frequency 5 Mhz, takes 415 or 0.8 microseconds to complete its execution. The same instruction when run on a microprocessor with 4Mhz clock frequency takes, 414, i.e. 1microseconds. NOP is used to produce the delay, without effecting the actual running of the program. Consider the following examples, in which you are trying a produce a time delay of 1ms, over a microprocessor, with a clock frequency of 5 MHz. Time taken for each clock cycle is 1/(5 MHz), which is equal to 0.2 micro seconds. To get a delay of 1 ms, we need to execute 100010.2 or 5000 processor clock cycles. The following program can be used to produce the delay, with the counter value correctly initialized. clock MOV cycles CX,N
;4 ;

N will vary depending on the amount of delay required

DELAY:

NOP NOP LOOP DELAY

;3 ;3

; 17 or 5

LOOP instruction takes 17 clock cycles when the condition is true and 5 clock cycles otherwise. The condition will be true, 'N' number of times and false only once, when the control comes out of the loop.

T o calculate 'N': Total clock cycles (CT)


= MOVE clock cycles

+ N(2*NOP clock-

A w m b l y Language Programming (Part-I)

cycles

+ 17) - 12 (when CX = 0)

+ N(6 + 17) - 12 N = (5000 + 8)/23 = 218 = ODAh


5000 = 4 Therefore the counter, CX, should be initialized by ODAh, in order to get the required delay.

Example 2 Array Application


This program adds a 5-byte number in one array, called NUMl to a Ebyte number in another array called N U M 2 The sum is stored in an array called SUM, with the state of the carry flag stored in byte 6 of SUM. The first value in each array is the LSB of that number. ALGORITHM : Make count
=

LEN

Clear the carry flag Load address of NUMl REPEAT Put byte from N U M l in accumulator Add byte rrom NUM2 to accumula~or+ carry

Decrement counl Increment to next address UNTIL count


=

Rotate carry into LSB of accumulator Mask all but LSB of accumulator Store carry result, address pointer in correct position. ;PORTS
: None uscd : None used : Uses CS, DS, AX, CX, BX, DX

;PROCEDURES ;REGISTERS

DATA

SEGMENT NUMl NUM2 SUM DB DB DB OFFh, lOh, 10h 2Oh,

, Olh
30h,

, l l h , 20h
40h

, OFFh

6DUP(O)

DATA

ENDS

\lic.roprocessor and A\sernhly 1.11npunp Proprnmnling

LEN CODE

EUU

05h

; constant

for length of thc array

SEGMENT ASSUME CS:CODE, DS:DATA

START:

MOV MOV MOV MOV MOV CLC

AX, DATA DS, AX BX, 00 CX, 0000 CL, LEN

; 1nitiali;rcdata segment

; register ; Load dispIaccment of 1st number ; Clear counter


; Set up count

; Clear carry. Ready for addition

AGAIN:

MOV ADC MOV I NC LOOP RCL AND MOV

AL, NUMl[BX] ; Get a byte from NUMl AL, NUM2[BX) ; Add to byte from NUM2 SUM[BX], AL ; Store in SUM array BX AGAIN AL, Olh AL, Olh
; Continue until no more bytes ; Move carry into bit 0 of AL

; Mask all but bit 0 of AL

SUM[BX],AL ; Put carry into 6th byte

FINISH:

NOP NOP

CODE

ENDS END START

Example 3 Code Conversion Consider the following program which converts a +digit BCD numbcr into its binary equivalent, The BCD number is srored as a word in memory location cal BCD. The result is stored in location HEX. ALGORITHM:
I

Use the example 4596 as the BCD number Put the BCD numbcr into 3 extended registers Take the first digit (4) Mask out the other three digits (4000) Multiply by 3EXh (1000) to gct 4000 Take the second digit (5) Mask out thc other three digits (0500)
=

OFAOh

Multiply by 64h (100) Add to first digit and get 4500 Take the third digit (9) Mask out the other three digits (0090) Multiply by 0Ah (10) Add to first and second digit to get 4590 Take the last digit (6) Mask out the other three digits (0006) Add to first, second, and third digit to get 4596 ;PORTS
: None used
=

1194h

llEEh

11F4h

;REGISTERS: Uses CS, DS, AX, CX, BX, DX THOU DATA EQU 3ESh
; 1000
=

3E8h

SEGMENT BCD HEX DW DW 4596h


?

;Storage reserved for result

DATA CODE

ENDS SEGMENT

ASSUME CS:CODE, DS:DATA START: MOV MOV MOV MOV MOV MOV AX,DATA DS,AX AX,BCD BX,AX AL,AH BH,BL
; Initialize data segment

; register ; Get the BCD number


; Copy number into BX

; Place for upper 2 digits ; Place for lower 2 digits ; split up numbers so that we have one ;digit in each register

MOV ROR ROR AND AND MOV

CL, 04 AH,CL BH,CL AX,OFOFH BX,OFOFH CX,AX

; Nibble count for rotate ; Digit 1 (MSB) in low nibble of AH ; Digit 3 in low nibble of BH

; Mask upper nibbles of each digit

; Digit 2 in low nibble of AL ; Digit 4 in low nibble of BL ; copy AX into CX so that can use AX for ; multiplication

Microprocemor and Assembly

Language Programming

MOV

A?(.Cw~fk!il

; Zero AH and AL ; now multiply each number by its place ;value

MOV MOV MUL

AL,CH D1,THOU DI

; Digit 1to AL for multiply ;No immediate multiplication

;digit 1* 1000
; Result in DX and AX. Because BCD digit ;will not be greater than 9999, the result ; will be in AX only. Zero DH and add BL ;because that digit needs no multiplication ; for place value. Then add the result in ;AX for digit 4

MOV MOV ADD MOV MUL ADD MOV MUL ADD MOV MOV
INT 21h

DH,OOH DL,BL DX,AX AX, 0064h CL DX,AX AX,OOOAh BH DX,AX HEX,DX AX,4C00h
: 5tcn.c digit 4 to DL
; Add

; cool inue with

digit 1 result to it multiplications

;Load value for 100 into AL

;Multiply by digit 2 from CL


;Add to total in DX
; Load value of 10 into AL

; Multiply by digit 3 in BH ;Add to total in DX


;Put result in HEX for return

CODE

ENDS END

START

Check Your Progress 3


1.

Why should we perform string processing in assembly language in 8086 and not in high level language?

...................................................................
2.
What is the function of direction flag in the second example given in 3.4.1?

...................................................................
3.

What is the function of NOP statement?

3.5

SUMMARY

In this unit, we have covered some basic aspects of assembly language programming. We started with some elementary arithmetic problems, code conversion problems, various types of loops and graduated on to do string processing and slightly complex arithmetic. As part of good programming practice, we also noted some points that should be kept in mind while coding. Some of them are:

Your program should always be preceded by an algorithm. It is a good programming practice. This not only increases the readability of the program,' but also makes your program less prone to logical errors.

- Use comments liberally. You will appreciated them later. - Study the instructions, assembler directives and addressing modes carefully, before starting to code your program. You can even use a debugger to get a clear understanding of the instructions and addressing modes. - Some instructions are very specific to the type of operand they are being used with, example signed numbers and unsigned numbers, byte operands and word operands, so be careful !!

Certain instructions expect some registers to be initialized by some values before being executed, example, LOOP expects the counter value to be contained in CX register, string instructions expect DS:SI to be initialized by the segment and the offset of the string instructions, and ES:DI to be with the destination strings, INT 21h expects AH register to contain the function number of the operation to be carried out, and depending on them some of the additional registers also to be initialized. So study them carefully and do the needful. In case you miss out on something, in most of the cases, you will not get an error message, instead the 8086 will proceed to execute the instruction, with whatever junk is lying in those registers.

Inspite of all these complications, assembly language is still an indispensable part of the programming, as it gives you an access to the most of the hardware features of the machine, which might not be possible with high level language. Secondly, as we have also seen some kind of applications can be written and efficiently executed in assembly language. In the preceeding text, we justified this with string processing instructions, you will appreciate it more, when you actually start the assembly language programming. You can now perform some simple exercises from the further readings. In the next block, we take up more advanced assembly language programming, which also includes accessing some hardware features of the machine.

Mkmpmeeswr and k m b l y
~.nlp.poy.=mlnp ~

36 .

MODEL ANSWERS

Check Your Progress 1


1.False 2. False 3. True 4. True 5. True 6. False

Check Your Regress 2


1.

MOV SUB MOV MOV IDIV IMUL

AX,A AX, B

;BringAinAX
;Subtract B

DX, O O h ;Move 0 to DX as it will be used for word division OO BX, 10 BX C


;Move Dividend to BX

;Divide ;((M-B) / 10 C) in AX ;Square AX to gel (A-B/10 C)

IMUL AX
2.

Assuming that each array element is a word variable. MOV MOV MOV CX, COUNT AX,OOOOh SI, AX
;Put the number of elements of the array in ;CX register
;Zero SI and AX

;Add the elements of array in AX again and


;again

AGAIN: ADD AX, ARRAY [SI] ;Another way of handling array ADD SI, 2
;Select the next element of the array
;Add all the elements of the array. It will
;terminate when CX becomes zero.

LOOP AGAIN

MOV
3.
4.

TOTAL, AX

;Store the results in TOTAL

Yes, because the conversion efforts are small. We may use two nested loop instructionsin assembly also. However, as both the loop instructions use CX, therefore, every time before we are entering inner loop we must push CX of outer loop in the stack and reinitialise CX to the inner loop requirements.

Check Your Rogress 3


1.

The object code generated on compiling high level languages for string processing commands is, in general, found to be long and contains several redundant instructions. However, we can perform string processing very efficiently in 8086 assembly language. Direction flag if clear will cause REPE statement to perform in forward direction. That is, in the given example the strings will be compared from first element to last. It produces a delay of a desired clock time in the execution. This instruction is useful while development of program. A collection of these instructions can be used to fill up some space in the code segment which can be changed with new code lines without disturbing position of existing code. This is particularly used when a label is specified.

2.

3.

You might also like