Free Tutorials, Linux Command, Source Code Architecture,  Software Engineering, Intelligent Systems, RDBMS, Computer Accounting,  Operations Research, Discrete Mathematics, Network, SAD Lay Networks Lay Networks
Computer Science Networking Operating Systems Linux and Unix Source Code Script & Languages Protocols Glossary
Web laynetworks.com
Google
 


Program in 8086 assembly language to multiply two 4 digit packed BCD nos.and print the result as ascii(decimal) value
contributed by Kailas Jagtap

.model small
.data

;Messages for user

s0 db 0dh,0ah,'MULTIPLICATION OF TWO 4 DIGIT PACKED BCD NUMBERS ..By Kailas Jagtap$'

s1 db 0dh,0ah,'Enter first 4-digit Decimal no (XXXX): $'

s2 db 0dh,0ah,'Enter second 4-digit Decimal no (XXXX): $'

s3 db 0dh,0ah,'Above nos. first converted to packed BCD form $'

s33 db 'and then to hex. form',0dh,0ah,0ah,'Packed BCD output : $'

s333 db 0dh,0ah,0ah,'Hexadecimal output : $'

s4 db 0dh,0ah,'Multiplication of above two nos.(printed in Hex) : $'

s44 db 0dh,0ah,'Multiplication of above two nos.(printed in ASCII) : $'

s5 db 0dh,0ah,' $'

s6 db 0dh,0ah,'***************** ERROR!!! - INVALID INPUT ****************** $'

n1 db 4 dup(0) ;storage for 1st no. from Keyboard (4 digits in unpacked ¼D form)

n2 db 4 dup(0) ;storage for 2nd no. from Keyboard (4 digits in unpacked ¼D form)

pnum1 dw 1 dup(0) ;2-byte storage for 1st no.(4 digits in packed BCD form)

pnum2 dw 1 dup(0) ;2-byte storage for 2nd no.(4 digits in packed BCD form)

unum1 db 4 dup(0) ;4-byte storage for 1st no.(4 digits in unpacked ¼D form)

unum2 db 4 dup(0) ;4-byte storage for 2nd no.(4 digits in unpacked BCD form)

;(unum1 & unum2(8 bytes)also used for storing upk remainders

;as they will become free after initial use)

hnum1 dw 1 dup(0) ;2-byte storage for 1st hex no.

hnum2 dw 1 dup(0) ;2-byte storage for 2nd hex no.

result dw 2 dup(0) ;4-byte storage for multiplication result(packed Hex)

uresult db 8 dup(0) ;8-byte storage for multiplication result(unpacked Hex)

quot db 8 dup(0) ;8-byte storage for quotient(unpacked Hex)

dividend dw 1 dup(0) ;2-byte storage for addr.of varying dividend

quotient dw 1 dup(0) ;2-byte storage for addr.of varying quotient

rmcnt db 1 dup(0) ;remainder counter

err_flg db 1 dup(0) ;error flag for indicating invalid i/p

.code

start:

mov ax,@data ;initialise ds with data seg. addr.

mov ds,ax

call disp_nl ;move cursor to new line

mov ah,9 ;display initial msg.

lea dx,s0

int 21h

call disp_nl ;move cursor to new line

call disp_nl ;move cursor to new line

mov err_flg,0 ;clear error flag

mov ah,9 ;display enter 1st no. msg.

lea dx,s1

int 21h

lea bx,n1 ;get 1st 4-dig.no. and store in

call input ;unpacked BCD form

cmp err_flg,0 ;is input invalid?

jz noerr ;if valid(z) go to get 2nd no.

;otherwise comeout flashing err msg

iperr: call disp_nl ;go to new line

call disp_nl ;go to new line

mov ah,9 ;display err msg.

lea dx,s6

int 21h

mov ah,4ch ;hand over control to DOS

int 21h

noerr: mov ah,9 ;display enter 2nd no. msg.

lea dx,s2

int 21h

lea bx,n2 ;get 2nd 4-dig.no.and store in

call input ;unpacked BCD form

cmp err_flg,0 ;is input invalid?

jnz iperr ;if yes(nz) comeout flashing err msg

;convert nos. n1 & n2 from unpacked to packed BCD

lea bx,n1 ;get 1st no.

call u_to_p ;convert

mov pnum1,ax ;store converted no.

lea bx,n2 ;get 2nd no.

call u_to_p ;convert

mov pnum2,ax ;store converted no.

;convert first no. from packed BCD to unpacked

lea si,pnum1 ;get addr. of 1st packed no.

lea di,unum1 ;get addr. for storing no. converted to unpacked form

call p_to_u ;convert from packed to unpacked

lea bx,unum1 ;get start addr. of 1st unpacked no.

call u_to_h ;convert 4 bytes of unpacked no. to equivalent 2 byte hex

mov hnum1,dx ;store converted hex no.

;convert second no. from packed BCD to Hex

lea si,pnum2 ;get addr. of 2nd packed no.

lea di,unum2 ;get addr. for storing no. converted to unpacked form

call p_to_u ;convert from packed to unpacked

lea bx,unum2 ;get start addr. of 2nd unpacked no.

call u_to_h ;convert 4 bytes of unpacked no. to equivalent 2 byte hex

mov hnum2,dx ;store converted hex no.

;display pk BCD and hex nos.

call disp_nl ;move cursor to new line

mov ah,9 ;display pk BCD output msg.

lea dx,s3

int 21h

lea dx,s33

int 21h

;display packed BCD nos.(pnum1 & pnum2)

lea si,pnum1 ;get addr.of 1st pk BCD no.(no.in 2 byte word)

call display ;display 1st pk BCD no.

call disp_nl ;move cursor to new line

lea si,pnum2 ;get addr.of 2nd pk BCD no.(no.in 2 byte word)

call display ;display 2nd pk BCD no.

mov ah,9 ;display hex output msg.

lea dx,s333

int 21h

;display hex nos.(hnum1 & hnum2)

lea si,hnum1 ;get addr.of 1st hex no.

call display ;display 1st hex no.

call disp_nl ;move cursor to new line

lea si,hnum2 ;get addr.of 2nd hex no.

call display ;display 2nd hex no.

;multiply nos.(in hex form) i.e. hnum1 X hnum2

mov ax,hnum1 ;get 1st no.

mov cx,hnum2 ;get 2nd no.

mul cx ;word to word mul.- result in dx(msb) & ax(lsb)

mov result,dx ;store msb part first

mov result+2,ax ;store lsb part

;display mul.result in hex form

call disp_nl ;move cursor to new line

call disp_nl ;move cursor to new line

mov ah,9 ;display mul.in hex msg.

lea dx,s4

int 21h

lea si,result ;get addr.of result (msb part)

call display ;display msb part

lea si,result+2 ;get addr.of result (lsb part)

call display ;display lsb part

;------------------

;convert result from packed(4 byte Hex) to unpacked(8 byte Hex)

lea si,result ;get addr. of result(msb)

lea di,uresult ;get addr. for storing no. converted to unpacked form

call p_to_u ;convert from packed to unpacked

lea si,result+2 ;get addr. of result(lsb)

lea di,uresult+4;get addr. for storing no. converted to unpacked form

call p_to_u ;convert from packed to unpacked

;display msg 'mul.result in ascii'

call disp_nl ;move cursor to new line

call disp_nl ;move cursor to new line

mov ah,9 ;display mul.in hex msg.

lea dx,s44

int 21h

;divide result(dividend) by 10 successively until quotient is <10

;collect remainders in each /10 and display them in reverse order

;which will be mul.result displayed in decimal

lea si,uresult ;get start add. of unpacked result

lea di,quot ;get start add. of unpacked quotient

;every quot has one digit less than dividend

nxt_div: mov [dividend],si ;save current pointers(addr.)

mov [quotient],di

mov dh,0ah ;get divisor 10

mov ah,[si] ;first get two msb digits(upk) for division(1st now & next in loop)

mov ch,8-1 ;counter(0-7) for dividing 8 upk digits

mov cl,4 ;counter for nibble shifting

div_agn: inc si ;point to next dig of current dividend

inc di ;point to next dig of current quotient

mov al,[si] ;get next dig and combine it with earlier

shl ah,cl ;remainder to carry out next division

or al,ah ;make 1 byte packed binary from 2 upk bytes

mov ah,0 ;(e.g. 02 0E converted to 00 2E bin )

div dh ;ax/dh, ah=rem (00 to 09 always) al=quo(00 to 0f always)

mov [di],al ;store current quot. dig in quotient

dec ch ;all 8 dig of dividend are divided?

jnz div_agn ;if not,get next dig for division

;otherwise, save current remainder(ah) on stack

mov al,0 ;only ah can not be pushed on stack

push ax ;save remainder on stack(which is upk BCD digit)

inc rmcnt ;incr.rem counter by 1

;check whether after successive div. quot. is reduced to <10

;i.e. first 7 bytes are 0 and last byte is <10

mov cl,0 ;counter for counting zeros in quotient

mov di,[quotient];get quotient start addr.

chk_z: mov ah,[di] ;get next dig from quotient

cmp ah,0 ;is dig 0 ?

jnz div_cont ;if not, continue dividing the quotient again

inc di ;otherwise point to next dig for checking

inc cl ;update zero counter

cmp cl,7 ;is it crossing 7 ?

jl chk_z ;if not(0-6), get next dig from quotient for checking

mov ah,[di] ;otherwise get last(8th)dig

cmp ah,9 ;is it <10 ?

jle disp_bcd ;if yes(0-9), go to display all remainders

;otherwise, continue dividing the quotient again

div_cont: mov si,[dividend];get start addr.of dividend

mov cl,8 ;counter for filling zeros

mov al,0 ;load zero

fz: mov [si],al ;fill a byte of dividend with 0

inc si ;point to next location

loop fz ;loop until all 8 bytes filled with 0

mov si,[quotient] ;now si will point to old quot.(treating it as new dividend)

mov di,[dividend] ;and di will point to old dividend (which will store new quot.)

jmp nxt_div ;go to divide quotient again

;

disp_bcd: call disp_ln ;ah=last rem, display it first

dbcd: pop ax ;ah=next rem in reverse order

call disp_ln ;display all rem one by one

dec rmcnt ;all rem over?

jnz dbcd ;if not,get next one

mov ah,4ch ;otherwise, hand over control to DOS

int 21h

;-----------------------------------------------------------------

;get 4-dig.no.from Keyboard and store in 4 byte buffer(in unpacked BCD form)

input PROC NEAR

mov cl,4 ;counter for 4 bcd dig i/p

again:

mov ah,1 ;dos int call for geting keyboard i/p

int 21h ;input is in al

cmp al,30h ;check for validity(below 0?)

jb inval ;if <30h, set err flg

cmp al,39h ;check for validity(beyond 9?)

jg inval ;if >39h, set err flg

sub al,30h ;make from ascii to bin

mov [bx],al ;store it in buffer

inc bx ;point to next location in buffer

dec cl ;all 4 i/p are over?

jnz again ;if not(nz), loop for next input

ret ;otherwise return, as 4 i/ps collected

inval: mov err_flg,0ffh ;set err flag

ret ;return immediately breaking i/p loop

input ENDP

;convert 4-digit BCD no. from unpacked(4 bytes) to packed(2 bytes) form

u_to_p PROC NEAR

mov ah,[bx] ;get 1st upk no.

mov cl,4 ;counter for nibble shifting

shl ah,cl ;shift right nibble to left e.g.change 03 to 30

inc bx ;point to next no.

add ah,[bx] ;add next no. to 1st shifted no.

inc bx ;point to next no.

mov al,[bx] ;get next upk no.

shl al,cl ;shift right nibble to left

inc bx ;point to next no.

add al,[bx] ;add next no. to no.shifted earlier

ret ;return with ax=packed no.

u_to_p ENDP

;Convert 4-digit BCD no. from packed(2 bytes) to unpacked(4 bytes)form

p_to_u PROC NEAR

mov ax,[si] ;get packed no.

call conv_pu ;first convert no.in ah to unpacked & store

mov ah,al ;then get no.in al for conversion

inc di ;point to next storage location

call conv_pu ;convert no.in al to unpacked & store

ret

p_to_u ENDP

conv_pu PROC NEAR

push ax ;save no.in ah for future use

and ah,0f0h ;mask lower nibble to extract upper nibble

mov cl,4 ;load shift count

shr ah,cl ;shift right 4 times to shift upper nibble to right

mov [di],ah ;store unpacked no. e.g. in packed 24h, 02 extracted

inc di ;point to next storage location

pop ax ;restore old no. in ah

and ah,0fh ;mask upper nibble to extract lower nibble

mov [di],ah ;store unpacked no. e.g. in packed 24h, 04 extracted

ret

conv_pu ENDP

;display 4-dig. hex no. available in a word(2 bytes)

;e.g bx=1234h i.e. bh=12h bl=34h

display PROC NEAR

mov bx,[si] ;get hex no. in bx(display bh & bl one by one)

call dis_byt ;first display upper byte(in bh)

mov bh,bl ;move byte in bl to bh for display

call dis_byt ;display lower byte

ret

display ENDP

dis_byt PROC NEAR

mov ah,bh ;get byte in ah

and ah,0f0h ;mask lower nibble

call conv_un ;conv. upper nibble of byte to ascii(result in ah)

call disp ;display upper nibble of byte in ah

mov ah,bh ;get byte in ah again

and ah,0fh ;mask upper nibble

disp_ln: call conv_ln ;conv. lower nibble of byte to ascii(result in ah)

call disp ;display lower nibble of byte in ah

ret

dis_byt ENDP

;convert upper nibble in byte from BCD to ascii

;input ah=BCD no. ouput ah=ascii code

conv_un PROC NEAR

shr ah,1 ;shift right 4 times e.g. 10h to 01h, add 30h

shr ah,1 ;to it to make it 31h(ascii for 1)

shr ah,1

shr ah,1

conv_ln:add ah,30h ;convert to ascii code(also used for conv.of lower nibble)

cmp ah,39h ;if no.>9 i.e.A to F add 7 to make

jle conv ;it corresponding displayable ascii code

add ah,7 ;e.g if 0C, 0C+7=13h, 13h+30h=43h(ascii for C)

conv: ret

conv_un ENDP

disp PROC NEAR

mov dl,ah ;int 21 needs byte(to be displayed) in dl

disp1: mov ah,2 ;select function no. of int 21

int 21h ;dos call for displaying byte in dl

ret

disp ENDP

disp_nl PROC NEAR ;move cursor to new line on screen

mov ah,9

lea dx,s5

int 21h ;display cr & lf

disp_nl ENDP

;convert 4-digit BCD no. from unpacked to equivalent hex form

;e.g. upk no. in 4 bytes - 01 02 03 04, hex no. in 2 bytes - 04D2 h

;bx=start addr.of upk BCD no. dx=actual hex no.

u_to_h PROC NEAR ;e.g 01 02 03 04 = 1x1000 + 2x100 + 3x10 + 4

mov ax,1000 ;First do calculation for 1000's place e.g. 1x1000

mov ch,0 ;word to word mul. so ch should be 0

mov cl,[bx] ;get upk BCD byte for mul.

mul cx ;ax X cx Result in dx(MSB) & ax(LSB)

;we can not use just 'mul cl' here, as 1000 D = 03E8 H

;which will require word mul. & not byte mul.

;after mul.dx=0 always, as max.is 1000x9=9000D=2328H

;which definately fit in 2 bytes(in ax), so we can

;spoil dx and use for other work

mov dx,ax ;save mul.result of 1000's place

push dx ;save dx as used in further mul.

mov ax,100 ;do calculation for 100's place e.g. 2x100

inc bx ;point to next byte of upk BCD

mov cl,[bx] ;again word mul.required as max is 9x100=900D=0384H

mul cx ;word to word mul.

pop dx ;get previously saved calculation of 1000's place

add dx,ax ;add calculations of 100's place and 1000's place

;dx not necessary to save as no word to word mul. further

mov ax,10 ;do calculation for 10's place e.g. 3x10

inc bx ;point to next byte of upk BCD

mov cl,[bx] ;byte mul.ok(word mul.not required as max.is 9x10=90D

mul cl ;which can fit in one byte only

add dx,ax ;add result to above addition of two places

inc bx ;point to next byte of upk BCD

mov cl,[bx] ;get no.at one's place

mov ch,0 ;word to word addition so ch should be 0

add dx,cx ;add last byte to above addition of three places(e.g add 4)

ret

u_to_h ENDP

end start

end

Back
FDDI Frequently Asked Questions (FAQ), The function and frame format of FDDI,Aloha,Comparative analysis between two types of ATM Switches,Knockout Switch,Barcher-Banyan Switch,Various popular standards for compressing multimedia data,Distributed Multimedia Survey: Standards, ASCII to hex value chart,Comparative analysis - TCP - UDP, Addressing Formats and QoS parameters, Bellman Ford's Algorithm Lay networks, free, java, java script, asp, vb, linux, ignou, tutorial, Unix commands, System Analysis, System Design, Ipv6, quiz, download, free, Computer Architecture, Object Oriented System, Relational Database Management Systems, Object Oriented System, Operating Systems, Software Engineering, Communications and Networks, Discrete Mathematics, Intelligent Systems, Operations Research, Accounting and Finance on Computersmca, networking, protocols, glossary, assignment, project, tma, programming source code, programming, source code, unix, free
 
Book Mark/Share this site at BlinkBits BlinkList Blogmarks co.mments Delicious Digg Fark Furl it! Google Ma.gnolia Netvouz NewsVine RawSugar Reddit Shadows Simpy Stumble Technorati YahooMyWeb

Copyright © 2000- 2007 Lay Networks All rights reserved. 
This website is best viewed in Firefox 1.0.1 above.

Web Hosting sponsored by Customized Software Company India
Web Site Designed by Web Designing, Flash Animation, Multimedia Presentations, Broacher/catalogue designing, Web Promotion 
Refer to your freind About Us Legal IGNOU Contact Us Feedback Donate to laynetworks.com Download Management Tutorials Tutorials History Search here