Wednesday, March 20, 2019

Write 80387 ALP to obtain: i) Mean ii) Variance iii) Standard Deviation

section .data

meanmsg db 10,"CALCULATED MEAN IS:-"
meanmsg_len equ $-meanmsg
sdmsg db 10,"CALCULATED STANDARD DEVIATION IS:-"
sdmsg_len equ $-sdmsg
varmsg db 10,"CALCULATED VARIANCE IS:-"
varmsg_len equ $-varmsg
array dd 102.56,198.21,100.67,230.78,67.93
arraycnt dw 05
dpoint db '.'
hdec dq 100  ;Write 64-bit floating-point constant

section .bss
dispbuff resb 1
resbuff rest 1 ;Reserve space for 80-bit floating-point constants

mean resd 1   ;Reserve double words (32 bits)
variance resd 1

%macro linuxsyscall 4
mov rax,%1
mov rdi,%2
mov rsi,%3
mov rdx,%4
syscall
%endmacro 


section .text
global _start
_start:

finit
fldz
mov rbx,array
mov rsi,00
xor rcx,rcx
mov cx,[arraycnt]

up:
fadd dword[RBX+RSI*4]
inc rsi
loop up

fidiv word[arraycnt]
fst dword[mean]
linuxsyscall 01,01,meanmsg,meanmsg_len
call dispres

mov rcx,00
mov cx,[arraycnt]
mov rbx,array
mov rsi,00
FLDZ

up1:

fld dword[array+rsi*4]              ;load the number
fsub dword[mean]                    ;st0(1st number)minus mean
fmul st0                            ;square it
fadd                                ;add st1=st0+st1
inc rsi   
loop up1

FIDIV word[arraycnt]
FST dword[variance]
FSQRT
linuxsyscall 01,01,sdmsg,sdmsg_len
CALL dispres

FLD dword[variance]
linuxsyscall 01,01,varmsg,varmsg_len
CALL dispres

exit:
mov rax,60
mov rdi,0
syscall


disp8_proc:
mov rdi,dispbuff
mov rcx,02

back:
rol bl,04
mov dl,bl
and dl,0FH
cmp dl,09
jbe next1
add dl,07H

next1:
add dl,30H
mov [rdi],dl
inc rdi
loop back
ret

dispres:
fimul dword[hdec]
fbstp tword[resbuff]
xor rcx,rcx
mov rcx,09H
mov rsi,resbuff+9

up2:
push rcx
push rsi
mov bl,[rsi]
call disp8_proc



linuxsyscall 01,01,dispbuff,2

pop rsi
dec rsi
pop rcx
loop up2

linuxsyscall 01,01,dpoint,1
mov bl,[resbuff]
call disp8_proc
linuxsyscall 01,01,dispbuff,2
ret

Write x86 ALP to find the factorial of a given integer number on a command line

%macro disp 2
mov rax,01h
mov rdi,01h
mov rsi ,%1
mov rdx,%2
syscall
%endmacro

%macro inn 2
mov rax,00h
mov rdi,00h
mov rsi,%1
mov rdx,%2
syscall
%endmacro

section .data
msg1 db "Enter the 8 bit number:",0ah,0dh
len1 equ $  -msg1

msg2 db "The factorial of given 8 bit number is:",0ah,0dh
len2 equ $  -msg2

msg3 db "The factorial for 0 or 1 is:",0ah,0dh
len3 equ $  -msg3

zeroonefact db "0001"
zeroonefactlen equ $-zeroonefact

section .bss
num resb 3
res resb 16

section .text
global _start
_start:

disp msg1, len1
inn num, 3
call accept

xor rax, rax
mov ax,bx
cmp ax,01h
jbe onezero

call factorial
call display
mov rax,60
mov rdi,0
syscall



onezero:
disp msg3,  len3
disp zeroonefact,  zeroonefactlen

;exit:


accept:
       mov rsi,num
       mov cl,04
       xor rbx,rbx
       mov ch,02
       up:
       cmp byte[rsi],39h
       jng sk
       sub byte[rsi],07h
       sk:
       sub byte[rsi],30h
       rol bl,cl
       add bl,[rsi]
       inc rsi
       dec ch
       jnz up
ret

factorial:
xor rbx, rbx
mov rbx,rax
up1:sub rbx ,01
mul rbx
cmp rbx,01
jne up1
ret

display:
mov rsi,res
mov ch,16
mov cl,04

again1:
rol rax,cl
mov bl,al
and bl,0fh
cmp bl,09h
jng skip2
add bl,07h
skip2:
add bl, 30h
mov [rsi],bl
inc rsi
dec ch
jnz again1

disp msg2, len2
disp res, 16
ret


Write X86 menu driven Assembly Language Program (ALP) to implement OS (DOS) commands TYPE, COPY and DELETE using file operations.

;macro.asm


%macro read 2
mov rax,0 ;read
mov rdi,0 ;stdin/keyboard
mov rsi,%1 ;buf
mov rdx,%2 ;buf_len
syscall
%endmacro

%macro print 2
mov rax,1 ;print
mov rdi,1 ;stdout/screen
mov rsi,%1 ;msg
mov rdx,%2 ;msg_len
syscall
%endmacro

%macro fopen 1
mov rax,2 ;open
mov rdi,%1 ;filename
mov rsi,2 ;mode RW
mov rdx,0777o ;File permissions
syscall
%endmacro

%macro fread 3
mov rax,0 ;read
mov rdi,%1 ;filehandle
mov rsi,%2 ;buf
mov rdx,%3 ;buf_len
syscall
%endmacro

%macro fwrite 3
mov rax,1 ;write/print
mov rdi,%1 ;filehandle
mov rsi,%2 ;buf
mov rdx,%3 ;buf_len
syscall
%endmacro

%macro fclose 1
mov rax,3 ;close
mov rdi,%1 ;file handle
syscall
%endmacro

%macro exit 0
print nline,nline_len
mov rax,60 ;exit
mov rdi,0
syscall
%endmacro

;file.asm

%include "macro.asm"
Section .data
title: db 0ah,"----Commands -----", 0ah
 db "1. Copy ",0ah
 db "2. Type ",0ah
 db "3. Delete ",0ah
 db "4. Exit ",0ah
 db "Enter Your choice",0ah
title_len: equ $-title

openmsg: db "File Opened Successfully",0ah,0dh
openmsg_len: equ $-openmsg
closemsg: db "File Closed Successfully",0ah,0dh
closemsg_len: equ $-closemsg
errormsg: db "Failed to open file", 0ah,0dh
errormsg_len: equ $-errormsg
delmsg: db "Deleted File", 0ah,0dh
delmsg_len: equ $-delmsg
typemsg: db "=-----File Contents ----=",0ah,0dh
typemsg_len: equ $-typemsg

f1name: db 'file1.txt',0
f2name: db 'file2.txt',0
f3name: db 'file3.txt',0

Section .bss
buffer: resb 200
bufferlen:resb 8
cnt1:resb 8
;fdis:resb 8
fhandle: resq 1
choice: resb 2

Section .text
global main
main:
write title,title_len
read choice,2

;------------- CHOOSE OPTION --------------------------
;compare choice here

cmp byte[choice],'1' ;if choice is to display content
je COPY
cmp byte[choice],'2'
je TYPE
cmp byte[choice],'3'
je DELETE
cmp byte[choice],'4'
je EXIT

COPY:
 fopen f1name  ;Opening file
 cmp rax, -1h
 je next
 mov [fhandle],rax
 ;mov qword[fdis],rax  ;RAX contains file descriptor value
 ;bt rax,63 ;63rd bit is +ve(0) if file is successfull opened else it is -ve (1)
 ;jc next

 write openmsg,openmsg_len
 jmp next1

next:
 write errormsg,errormsg_len
 jmp EXIT

next1:
 fread [fhandle],buffer,200    ;reading contents of file in buffer
  ;rax contains actual number of bytes read
 mov qword[bufferlen],rax
 mov qword[cnt1],rax

 ;Closing file1
  fclose f1name

 write closemsg,closemsg_len




;-------------------FILE 2 ------------------
 fopen f2name

 cmp rax, -1h
 je next3
 mov [fhandle],rax
 ;mov qword[fhandle],rax  ;RAX contains file descriptor value
 ;bt rax,63 ;63rd bit is +ve(0) if file is successfull opened else it is -ve (1)
 ;jc next3

 write openmsg,openmsg_len
 jmp next21

next3:
 write errormsg,errormsg_len
 jmp EXIT

next21:
 fwrite qword[fhandle],buffer,qword[bufferlen]            ;writing to file2.txt

 fclose f2name

 write closemsg,closemsg_len
 jmp main

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

TYPE:
 fopen f2name ;Opening file
 cmp rax, -1h
 je tnext
 mov [fhandle],rax
 ;mov qword[fdis],rax     ;RAX contains file descriptor value
 ;bt rax,63 ;63rd bit is +ve(0) if file is successfull opened else it is -ve (1)
 ;jc tnext

 write openmsg,openmsg_len
 jmp tnext1

tnext:
 write errormsg,errormsg_len
 jmp EXIT

tnext1:
 fread [fhandle],buffer,200 ;reading contents of file in buffer
 mov qword[bufferlen],rax
 write typemsg,typemsg_len
 write buffer,qword[bufferlen]

 ;Closing file2
 fclose f2name

 write closemsg,closemsg_len
JMP main

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

DELETE:
 mov rax,87 ;System CALL FOR UNLINK
 mov rdi,f3name
 syscall
 write delmsg,delmsg_len
jmp main

EXIT:
 mov rax,3ch
 mov rdi,00
 syscall

Write X86 ALP to find, a) Number of Blank spaces b) Numberof lines c) Occurrence of a particular character. Accept the data from the text file. The text file has to be accessed during Program_1 execution and write FAR PROCEDURES in Program_2 for the rest of the processing. Use of PUBLIC and EXTERN directives is mandatory

;macro.asm

;macros as per 64 bit conventions

%macro read 2
mov rax,0 ;read
mov rdi,0 ;stdin/keyboard
mov rsi,%1 ;buf
mov rdx,%2 ;buf_len
syscall
%endmacro

%macro print 2
mov rax,1 ;print
mov rdi,1 ;stdout/screen
mov rsi,%1 ;msg
mov rdx,%2 ;msg_len
syscall
%endmacro

%macro fopen 1
mov rax,2 ;open
mov rdi,%1 ;filename
mov rsi,2 ;mode RW
mov rdx,0777o ;File permissions
syscall
%endmacro

%macro fread 3
mov rax,0 ;read
mov rdi,%1 ;filehandle
mov rsi,%2 ;buf
mov rdx,%3 ;buf_len
syscall
%endmacro

%macro fwrite 3
mov rax,1 ;write/print
mov rdi,%1 ;filehandle
mov rsi,%2 ;buf
mov rdx,%3 ;buf_len
syscall
%endmacro

%macro fclose 1
mov rax,3 ;close
mov rdi,%1 ;file handle
syscall
%endmacro

%macro exit 0
print nline,nline_len
mov rax,60 ;exit
mov rdi,0
syscall
%endmacro

;file1.asm



extern far_proc ; [ FAR PROCRDURE 
;   USING EXTERN DIRECTIVE ]

global filehandle, char, buf, abuf_len

%include "macro.asm"

;------------------------------------------------------------------------
section .data
nline db 10
nline_len equ $-nline

ano db 10,10,10,10,"ML assignment 05 :- String Operation using Far Procedure"
db    10,"---------------------------------------------------",10
ano_len equ $-ano

filemsg db 10,"Enter filename for string operation : "
filemsg_len equ $-filemsg
  
charmsg db 10,"Enter character to search : "
charmsg_len equ $-charmsg

errmsg db 10,"ERROR in opening File...",10
errmsg_len equ $-errmsg

exitmsg db 10,10,"Exit from program...",10,10
exitmsg_len equ $-exitmsg

;---------------------------------------------------------------------------
section .bss
buf resb 4096
buf_len equ $-buf ; buffer initial length

filename resb 50
char resb 2
 
filehandle resq 1
abuf_len resq 1 ; actual buffer length

;--------------------------------------------------------------------------
section .text
global _start
_start:
print ano,ano_len ;assignment no. 

print filemsg,filemsg_len
read filename,50
dec rax
mov byte[filename + rax],0 ; blank char/null char

print charmsg,charmsg_len
read char,2
fopen filename ; on succes returns handle
cmp rax,-1H ; on failure returns -1
jle Error
mov [filehandle],rax

fread [filehandle],buf, buf_len
mov [abuf_len],rax

call far_proc
jmp Exit

Error: print errmsg, errmsg_len

Exit: print exitmsg,exitmsg_len
exit
;-------------------------------------------------------------------------------- 

file2.asm

;---------------------------------------------------------------------
section .data
nline db 10,10
nline_len: equ $-nline

smsg db 10,"No. of spaces are : "
smsg_len: equ $-smsg
nmsg db 10,"No. of lines are : "
nmsg_len: equ $-nmsg

cmsg db 10,"No. of character occurances are : "
cmsg_len: equ $-cmsg

;---------------------------------------------------------------------
section .bss

scount resq 1
ncount resq 1
ccount resq 1

char_ans resb 16

;---------------------------------------------------------------------
global far_proc

extern filehandle, char, buf, abuf_len

%include "macro.asm"
;---------------------------------------------------------------------
section .text
global _main
_main:

far_proc:          ;FAR Procedure
xor rax,rax
xor rbx,rbx
xor rcx,rcx
xor rsi,rsi

mov bl,[char]
mov rsi,buf
mov rcx,[abuf_len]

again: mov al,[rsi]

case_s: cmp al,20h ;space : 32 (20H)
jne case_n
inc qword[scount]
jmp next

case_n: cmp al,0Ah ;newline : 10(0AH)
jne case_c
inc qword[ncount]
jmp next

case_c: cmp al,bl ;character
jne next
inc qword[ccount]

next: inc rsi
dec rcx ;
jnz again ;loop again

print smsg,smsg_len
mov rax,[scount]
call display
print nmsg,nmsg_len
mov rax,[ncount]
call display

print cmsg,cmsg_len
mov rax,[ccount]
call display

fclose [filehandle]
ret

;------------------------------------------------------------------
display:
mov rsi,char_ans+3 ; load last byte address of char_ans in rsi
mov rcx,4 ; number of digits 

cnt: mov rdx,0 ; make rdx=0 (as in div instruction rdx:rax/rbx)
mov rbx,10 ; divisor=10 for decimal and 16 for hex
div rbx
; cmp dl, 09h ; check for remainder in RDX
; jbe  add30
; add  dl, 07h 
;add30:
add dl,30h ; calculate ASCII code
mov [rsi],dl ; store it in buffer
dec rsi ; point to one byte back

dec rcx ; decrement count
jnz cnt ; if not zero repeat
print char_ans,4 ; display result on screen
ret
;----------------------------------------------------------------

Write X86/64 ALP to perform multiplication of two 8-bithexadecimal numbers. Use successive addition

section .data
msg1 db "Enter First 8 bit HEX no: ",10
len1: equ $ -msg1
msg2 db "Enter Second 8 bit HEX no: ",10
len2: equ $ -msg2
msg3 db "Multiplication of two HEX no is: ",10
len3: equ $ -msg3

section .bss

arr1 resb 3
arr2 resb 3
arr3 resb 4
 %macro disp 2
mov rax,01h
mov rdi,01h
mov rsi,%1
mov rdx,%2
syscall
%endmacro

%macro inn 2
mov rax,00h
mov rdi,00h
mov rsi,%1
mov rdx,%2
syscall
%endmacro

section .text
global _start
_start:

disp msg1,len1
inn arr1,03
disp msg2,len2
inn arr2,03

mov rsi,arr1
mov cl,04
xor bx,bx
mov ch,02
up:
cmp byte[rsi],39h
jng sk
sub byte[rsi],07h
sk:
sub byte[rsi],30h
shl bx,cl
add bl,[rsi]
inc rsi
dec ch
jnz up

xor dx,dx
mov rsi,arr2
mov cl,04
mov ch,02
up1:
cmp byte[rsi],39h
jng sk1
sub byte[rsi],07h
sk1:
sub byte[rsi],30h
shl dx,cl
add dl,[rsi]

inc rsi
dec ch
jnz up1

xor ax,ax
xor cl,cl
cmp dl,bl
jng sph
mov cl,bl
mov bl,dl
jmp outt
sph:
mov cl,dl
outt:
add ax,bx
dec cl
jnz outt

mov rsi,arr3
mov ch,04
mov cl,04
again1:
rol ax,cl
mov bl,al
and bl,0fh
cmp bl,09h
jng skip2
add bl,07h
skip2:
add bl,30h
mov [rsi],bl
inc rsi
dec ch
jnz again1

disp msg3,len3
disp arr3,04

mov rax,3ch
mov rdi,00
syscall


output:-
[student@localhost Desktop]$ nasm -f elf64 mul.asm
[student@localhost Desktop]$ ld -o mul  mul.o
[student@localhost Desktop]$ ./mul
Enter First 8 bit HEX no:
04
Enter Second 8 bit HEX no:
02
Multiplication of two HEX no is:
0008[student@localhost Desktop]$


Write X86/64 ALP to convert 4 -digit Hex number into its equivalent BCD number and 5-digit BCD n umber into its equivalent HEX number. Make your program user friendly to accept the choice from user for:(a) HEX to BCD b) BCD to HEX (c) EXIT.Display proper strings to prompt the user while accepting the input and displaying the result. (wherever necessary, use 64-bit registers)

section .data
msg db "welcome to code converter",10
len equ $ -msg
msg1 db "1.enter your choice",10,"1.hexa to bcd",10,"2.bcd to hex",10,"3.exit",10
len1 equ $ -msg1
msg2 db "enter 16 hex no",10
len2 equ $ -msg2
msg3 db "enter bcd to convert in hex no ",10
len3 equ $ -msg4
msg4 db "hex no for given bcd no is:",10
len4 equ $ -msg5
msg6 db "bcd to given hex no is",10
len6 equ $ -msg6
msg5 db "thank you",10
len5 equ $ -msg6

section .bss
n resb 2
hex resb 5
bcd resb 6

%macro disp 2
mov rax,01
mov rdi,01
mov rsi,%1
mov rdx,%2
syscall
%endmacro

%macro inn 2
mov rax,00
mov rdi,00
mov rsi,%1
mov rdx,%2
syscall
%endmacro

section .text
global _start
_start:
disp msg,len
again:
disp msg1,len1
inn n,02

cmp byte[n],31h ;choice for option 1,2 and 3 comapring with choice 1
jne BCD ;if not equal to 1 then go to BCD

disp msg2,len2
inn hex,05 ;Taking HEX input of 4 digit and one for enter     FFFF

xor rax,rax
mov rsi,hex ;rsi is pointing to Hex input
mov cl,04 ;counter for left shift size 4
mov ch,04 ;Counter for no of digits 4
up:
cmp byte[rsi],39h ;compare first digit of hex input with 39h with 46H(F)
jng skip1 ;jump not grater to skip1 if number is smaller then 9(46>39)
sub byte[rsi],07h ;if number is greater then 39h then subtract from (46h-7h=3F)
skip1: ;
sub byte[rsi],30h ;subtract (3f-30h=F)
shl rax,cl ;shift left ax register by 4 bits it will be zero only
add al,[rsi] ;now F will be added to lower bits of AX   
inc rsi ;now rsi will point to second F of FFFF
dec ch ;ch will be 3 now

jnz up ;jump not zero to up until all digit of FFFF are added in RAX

xor ebx,ebx ;make EBX zero
mov bl,0Ah ;Bl register holds 0Ah,0A is hex equvivalent of 16 decimal number
xor edx,edx ;make EDX empty
mov rsi,bcd ;RSI will point to the resultant
add rsi,04 ;rsi will point to the end of rsi (5th place of bcd array)

up1:
div ebx ;RAX=FFFF and EBX=0Ah after division quotient will be in EAX and remainder will be in ;EDX  ,after first iteration EAX=  1999 and EDX= 5 
mov [rsi],dl ;move dl to BCD where RSI is pointing

xor edx,edx
dec rsi ;RSI is pointing to previous locatioin
cmp eax,00 ;until quotient became zero ,quotient became zero in 5th iteration
jne up1


;l1st iteration FFFF/0A= 1999 and [FFFF-FFFA] =5 remainder   -------EAX=1999  & EDX=5
;Second iteration   1999/A=28F and [1999-1996]=3 remainder ---------EAX=28F   & EDX=3
;third iteration    28F/A=41H and [28F-28A]=5 remainder-----------EAX=41H   & EDX=5
;Fourth iteration   41H/AH=06   and [41-3C]=5 remainder-------------EAX=06H   & EDX=5
;Fifth iteration 06/A=0 and [6-0]=6  remainder -------------EAX=0H    & EDX=6











mov rsi,bcd
mov cl,05

up2: ;this loop is converting Decimal to ASCII
add byte[rsi],30h ;First number of [rsi] is 6 so 6+30h=36H this loop conver all decimal to ascii
inc rsi
dec cl
jnz up2

disp msg6,len6
disp bcd,05 ;display output BCD number 65535
jmp again

BCD:
cmp byte[n],32h ;if choice is 2 then BCD to HEX conversion
jne exit

disp msg2,len2
inn bcd,06 ;if BCD=65535 is input number

xor rax,rax ;rax is empty
mov rsi,bcd ;rsi is pointing to BCD number 65535
mov ch,05

uphex:
sub byte[rsi],30h ;Number is stored in ascii so this loop is converting from ascii to decimal
inc rsi
dec ch
jnz uphex

mov cl,05h ;INITIALIZE COUNTER TO 5 since input is 5 digit
mov rsi,bcd ;rsi is pointing to BCD

j1:
add dx,0Ah ;add multiplicant 0Ah=16 decimal in DX register
mul dx ;MULTIPY ax*dx
xor bx,bx
mov bl,[rsi]
add al,bl ;l1st iteration 0*Oah=0                    EAX=0  & EDX=0a
inc rsi ;Second iteration       6*0aH=3c            EAX=3C   EDX=0a
;tHIRD iteration       3c+5=41H   41H*0a=28A      EAX=28a   EDX=0a
;FOURTH  ITERATION     28A+5=28f   28F*0A=1996    eax=1996  edx=0A
;fIFTH ITERATION      1996+3=1999   1999*A=FFFA   EAX=FFFA  EDX=0a
;sixth iteration      FFFA+5=FFFF    cl=0     EAX=FFFF






dec cl                                  ;at the end cl become zero
jnz j1

mov rsi,hex                             ;Hex is blank currently
add rsi,03 ;rsi points to end of hex
mov ch,04 ;ch is 4 for no of digits
mov cl,04 ;cl is 04 for shifting
as:
mov bl,al ;Move the FF to BL register from AX
and bl,0fh ;AND FF with 0F so result is 0F

cmp bl,09h ;compare 0F>09
jng skip6 ;jump if not greater
add bl,07h ;add 0F+7=16H
skip6:
add bl,30h ;add 16+30h=46H(It is ascii value of F)
mov [rsi],bl
shr rax,cl
dec rsi
dec ch
jnz as
disp msg4,len4
disp hex,04
jmp again

exit:
cmp byte[n],33h
je sn
sn:
disp msg5,len5
mov rax,3ch
mov rsi,00
syscall




Write X86/64 ALP to perform overlapped block transfer (with and without string specific instructions). Block containing data can be defined in the data segment

section .data
msg db "enter an offset:",10
len: equ $-msg

arr1 db "se computer",0ah
len1: equ $-arr1

section .bss
n resb 2
len4 resb 2

%macro disp 2
mov rax,01
mov rdi,01
mov rsi,%1
mov rdx,%2
syscall
%endmacro

%macro inn 2
mov rax,00
mov rdi,00
mov rsi,%1
mov rdx,%2
syscall
%endmacro

section .text
global _start
_start:

disp msg,len
inn n,2

cmp byte[n],39h
jng skip
sub byte[n],07h
skip:
sub byte[n],30h

mov rsi,arr1+len1-1
mov rdi,rsi
mov rcx,len1
xor rax,rax
mov al,[n]

add rdi,rax

;up:
;mov al,[rsi]
;mov [rdi],al
;dec rdi
;dec rsi
;dec cl
;jnz up
;mov al,[n]
;mov len4,al

std
rep movsb

disp arr1,len1+len4
mov rax,3ch
mov rdi,00
syscall

Write X86/64 ALP to perform non-overlapped transfer (with and without string specific instructions). Block containing data can be defined in the data segment

section .data
msg1 db "the source block is:",0ah,0dh
len1: equ $-msg1
msg2 db "the destination block is:",0ah,0dh
len2: equ $-msg2

arr1 db "se computer",0ah
len: equ $-arr1

section .bss
arr2: resb len

%macro disp 2
mov rax,01
mov rdi,01
mov rsi,%1
mov rdx,%2
syscall
%endmacro

section .text
global _start
_start:


mov rsi,arr1
mov rdi,arr2
mov rcx,len

xor al,al ;without using movsb
up: ; copy the string character by character to the destination
mov al,[rsi]
mov [rdi],al
inc rsi
inc rdi
dec rcx
jnz up


;cld
;rep movsb                                 ;comment need to be removed for movsb
   ; copy entire string at a time to destination
disp msg1,len1
disp arr1,len
disp msg2,len2
disp arr2,len

mov rax,3ch
mov rdi,00
syscall

Write X86/64 ALP to count number of positive and negative numbers from the array

section .data
 ncnt db 0
 pcnt db 0
 array: dw -80H,4CH,-3FH
 len equ 3
 msg1: db 'positive numbers are:',0xa
 len1: equ $-msg1
 msg2: db 'negative numbers are:',0xa
 len2: equ $-msg2


section .bss
 buff resb 02

section .text

 global _start
 _start:

  mov rsi,array
  mov rcx,03

  A1:
  bt word[rsi],15
  jnc A
  inc byte[ncnt]
  jmp skip

  A:
  inc byte[pcnt]
 

  skip:
  inc rsi
  inc rsi
  loop A1

  mov rax,1
  mov rdi,1
  mov rsi,msg1
  mov rdx,len1
  syscall
 
  mov bl,[pcnt]
  mov rdi,buff
  mov rcx,02

 
 
  call display

 
  mov rax,1
  mov rdi,1
  mov rsi,msg2
  mov rdx,len2
  syscall

  mov bl,[ncnt]
  mov rdi,buff
  mov rcx,02

 
  call display

  mov rax,60
  mov rdi,0
  syscall

  display:
  rol bl,4
  mov al,bl
  and al,0FH
  cmp al,09
  jbe B
                add al,07h

  B:
  add al,30H
  mov[rdi],al
  inc rdi
  loop display

 
  mov rax,1
  mov rdi,1
  mov rsi,buff
  mov rdx,02
  syscall
 
  ret

  

Friday, February 15, 2019


Write X86 program to sort the list of integers in ascending/descending order. Read the input from the text file and write the sorted data back to the same text file using bubble sort

 Algorithm for Bubble Sort
Bubble sort algorithm works by comparing the first two elements of an array and swapping if necessary, i.e., if you want to sort the elements of array in ascending order and if the first element is greater than second then, you need to swap the elements but, if the first element is smaller than second, you need not swap the element. Then, again second and third elements are compared and swapped if it is required and this process go on until last and second last element is compared and swapped. This completes the first pass of bubble sort. By doing this we bubble out the largest element at the last location in the array.
If there are n elements to be sorted then, the process mentioned above should be repeated n times to get the sorted array. As, in each pass one element is bubbled out. So to place all the elements in the unsorted array at their proper place we need to repeat the above said process for n times.
 Following figure will give you better understanding of bubble sort:


Figure: working of Bubble Sort


j=bufferlen-1
while(j>0)
{
        i=cnt1=bufferlen-1
        while(i>0)
        {
            if(a[i]>a[i+1])
                  swap(a[i],a[i+1])
            i--;
        }
j--;
}



b_sort2.asm (64-bit nasm code file) 

%macro file 4
mov rax,%1
mov rdi,%2
mov rsi,%3
mov rdx,%4
syscall
%endmacro

Section .data
accept_fn db "Enter file name",10,13
accept_fn_len equ $-accept_fn

openmsg db 10,13,"File Opened Successfully"
openmsg_len equ $-openmsg

closemsg db 10,13,"File Closed Successfully"
closemsg_len equ $-closemsg

errormsg db 10,13,"Failed to open file", 0xa
errormsg_len equ $-errormsg

space db " "
space_len equ $ - space

sortmsg db 10,13,"After Sorting "
sortmsg_len equ $-sortmsg

Section .bss
buffer resb 200
bufercpy resb 200
bufferlen resb 8
filename resb 50
cnt1 resb 8
cnt3 resb 8
fdisplay resb 8

Section .text
global _start
_start:
file 1,1,accept_fn,accept_fn_len
file 0,0,filename,50
dec    rax
mov    byte[filename + rax],0           ; blank char/null char

file 2, filename, 2, 777         ; Opening filein read-write mode with permission to read write   
                                              and execute to all(owner, group and other)

mov qword[fdisplay], rax      ;RAX contains file descriptor value
cmp    rax,-1H                      ; on failure returns -1
je    ERROR                         ; if file is successfull opened rax is +ve else it is -ve
                       
file 1,1,openmsg, openmsg_len
jmp next1

ERROR:
file 1,1, errormsg, errormsg_len
jmp EXIT

next1:
file 0,[fdisplay] ,buffer,200           ; reading contents of file in buffer
                                                    ; rax contains actual number of bytes read
 mov qword[bufferlen],rax            ; Total number of passes
 mov qword[cnt1],rax                   ; number of comparisons within a single pass
 mov qword[cnt3],rax                   ; total number of elements to be sorted
 dec byte[bufferlen];

BUBBLE:
mov al, byte[bufferlen];
mov byte[cnt1],al

mov rsi,buffer
mov rdi,buffer+1

loop:
mov bl,byte[rsi]
mov cl,byte[rdi]
 cmp bl,cl
 ja SWAP
 inc rsi
 inc rdi
 dec byte[cnt1]
 jnz loop
           
dec byte[bufferlen]
jnz BUBBLE
jmp END

SWAP:

 mov byte[rsi],cl
 mov byte[rdi],bl
 inc rsi
 inc rdi
 dec byte[cnt1]
 jnz loop
dec byte[bufferlen]
jnz BUBBLE

END:
file 1,1, sortmsg,sortmsg_len                           ;writing onto output screen
file 1,1, buffer,qword[cnt3]

file 1,qword[fdisplay],sortmsg,sortmsg_len      ;writing to input.txt
file 1,qword[fdisplay],buffer,qword[cnt3]           ;writing to input.txt

;Closing file
mov rax,3
mov rdi,filename
syscall

file 1,1, closemsg,closemsg_len

EXIT:
 mov rax,60
 mov rdi,0
 syscall




input.txt
5
4
3
2
1

Output:
[root@localhost ~]# nasm -f elf64 b_sort2.asm
[root@localhost ~]# ld -o s b_sort2.o
[root@localhost ~]# ./s
Enter file name
input.txt

File Opened Successfully
After Sorting
12345
File Closed Successfully[root@localhost ~]#

input.txt file content
5
4
3
2
1
After Sorting
12345



Monday, January 28, 2019

Write X86/64 ALP to perform multiplication of two 8-bit hexadecimal numbers. Use add and shift method.(use of 64-bit registers is expected)




Flowchart of Multiplication Algorithm

     Example:
                 Using 4-bit numbers, perform the multiplication 9 × 12 (1001 × 1100).

                        
Step
Ax
Dx
Bx
Operation
0
0000 0000
1100
0000 1001
Initialization
1
0000 0000
0000 0000

1100
0110

0001 0010
0001 0010
Shift left B
Shift right Q
2
0000 0000
0000 0000

0110
0011
0010 0100
0010 0100
Shift left B
Shift right Q
3
0010 0100
0010 0100
0010 0100

0011
 0011
0001

0010 0100
0100 1000 0100 1000
Add B to A
Shift left B
Shift right Q
4
0110 1100
0110 1100
0110 1100

0001
 0001
 0000

0100 1000
1001 0000
1001 0000

Add B to A
 Shift left B
Shift right Q
                                                    



64-bit nasm code

section .data
            innum1 db "Enter First 8 bit HEX no: ",10
            lennum1 equ $ -innum1
            innum2 db "Enter Second 8 bit HEX no: ",10
            lennum2 equ $ -innum2
            product db "Multiplication of two HEX no is: ",10
            productlen equ $ -product

section .bss
            num1 resb 3
            num2 resb 3
            result resb 4

%macro output 2                  ;macro for output
            mov rax,01h
            mov rdi,01h
            mov rsi,%1
            mov rdx,%2
            syscall
%endmacro

%macro input 2                    ;macro for input
            mov rax,00h
            mov rdi,00h
            mov rsi,%1
            mov rdx,%2
            syscall
%endmacro

section .text
global _start
 _start:
            output innum1,lennum1
            input num1,03
            output innum2,lennum2
            input num2,03
           
            mov rsi,num1
           call AtoH
           mov bx,ax

            mov rsi,num2
           call AtoH
           mov dx,ax
; Actual logic for multiplication of two numbers using add and shift method
                                                                
            xor ax,ax
            mov ch,08
again:
            bt dx,0   
            jnc skip1   
           add ax,bx   
skip1:   
           shl bx,1  
            shr dx,1
            dec ch
            jnz again

; logic to convert HEX to ASCII

            mov rsi,result
            mov ch,04
            mov cl,04
again1:
            rol ax,cl
            mov bl,al
            and bl,0fh
            cmp bl,09h
            jng skip2
            add bl,07h
skip2:
            add bl,30h
            mov [rsi],bl
            inc rsi
            dec ch
            jnz again1

            output product, productlen
            output result,04
mov rax,3ch
mov rdi,00
syscall

;procedure to convert ASCII to HEX

AtoH:
            xor ax,ax
            mov cl,04
            mov ch,02
up:
            cmp byte[rsi],39h
            jng down
            sub byte[rsi],07h
down:
            sub byte[rsi],30h
            shl ax,cl
            add al,[rsi]
            inc rsi
            dec ch
            jnz up
ret

Output:
[root@localhost ~]# nasm -f elf64 mul.asm
[root@localhost ~]# ld -o mul mul.o
[root@localhost ~]# ./mul
Enter First 8 bit HEX no: 15
Enter Second 8 bit HEX no: 12
Multiplication of two HEX no is: 017A