Thursday, May 27, 2021

Write a switch case driven X86/64 ALP to perform 64-bit hexadecimal arithmetic operations (+,-,*, /) using suitable macros. Define procedure for each operation.

 %macro scall 4

        mov rax,%1

        mov rdi,%2

        mov rsi,%3

        mov rdx,%4

        syscall

%endmacro


section .data

        arr dq 000000000000007h,0000000000000002h

        n equ 2


        menu db 10d,13d,"**********MENU**********"

             db 10d,13d,"1. Addition"

             db 10d,13d,"2. Subtraction"

             db 10d,13d,"3. Multiplication"

             db 10d,13d,"4. Division"

             db 10d,13d,"5. Exit"

             db 10d,13d,"Enter your Choice: "

        menu_len equ $-menu


        m1 db 10d,13d,"Addition: "

        l1 equ $-m1

        m2 db 10d,13d,"Substraction: "

        l2 equ $-m2

        m3 db 10d,13d,"Multiplication: "

        l3 equ $-m3

        m4 db 10d,13d,"Division: "

        l4 equ $-m4

section .bss

        answer resb 16 ;to store the result of operation

        choice resb 2


section .text

        global _start:

        _start:


        up: scall 1,1,menu,menu_len

        scall 0,0,choice,2

        cmp byte[choice],'1'

        je case1

        cmp byte[choice],'2'

        je case2

        cmp byte[choice],'3'

        je case3

        cmp byte[choice],'4'

        je case4

        cmp byte[choice],'5'

        je case5


        case1: scall 1,1,m1,l1

                call addition

                jmp up

        case2: scall 1,1,m2,l2

        call substraction

        jmp up


        case3: scall 1,1,m3,l3

        call multiplication

        jmp up


        case4: scall 1,1,m4,l4

        call division

        jmp up

        case5:  mov rax,60

        mov rdi,0

                syscall

;procedures for arithmetic and logical operations

addition:

        mov rcx,n

        dec rcx

        mov rsi,arr

        mov rax,[rsi]

up1:    add rsi,8

        mov rbx,[rsi]

        add rax,rbx

        loop up1

        call display

    ret

substraction:

        mov rcx,n

        dec rcx

        mov rsi,arr

        mov rax,[rsi]

up2:    add rsi,8

        mov rbx,[rsi]

        sub rax,rbx

        loop up2

        call display

ret

multiplication:

        mov rcx,n

        dec rcx

        mov rsi,arr

        mov rax,[rsi]

up3:    add rsi,8

        mov rbx,[rsi]

        mul rbx

        loop up3

        call display

ret


division:

        mov rcx,n

        dec rcx

        mov rsi,arr

        mov rax,[rsi]

up4:    add rsi,8

        mov rbx,[rsi]

        mov rdx,0

        div rbx

        loop up4

        call display

ret



display:

        mov rsi,answer+15

        mov rcx,16


cnt:    mov rdx,0

        mov rbx,16

        div rbx

        cmp dl,09h

        jbe add30

        add dl,07h

add30:  add dl,30h

        mov [rsi],dl

        dec rsi

        dec rcx

        jnz cnt

        scall 1,1,answer,16

ret

Write an X86/64 ALP to accept a string and to display its length.

 section .data

msg1 db 10,13,"Enter a string:"

len1 equ $-msg1


section .bss

str1 resb 200                 ;string declaration

result resb 16


section .text


global _start

_start:


;display

mov Rax,1

mov Rdi,1

mov Rsi,msg1

mov Rdx,len1

syscall


;store string 


mov rax,0

mov rdi,0

mov rsi,str1

mov rdx,200

syscall


call display


;exit system call

mov Rax ,60

mov Rdi,0

syscall



%macro dispmsg 2

mov Rax,1

mov Rdi,1

mov rsi,%1

mov rdx,%2

syscall

%endmacro




display:

mov rbx,rax                      ; store no in rbx

mov rdi,result                   ;point rdi to result variable 

mov cx,16                        ;load count of rotation in cl  


up1: 

rol rbx,04               ;rotate no of left by four bits

mov al,bl          ; move lower byte in dl

and al,0fh               ;get only LSB

cmp al,09h               ;compare with 39h

jg add_37                ;if greater than 39h skip add 37    

add al,30h                

jmp skip                 ;else add 30     

add_37: 

add al,37h                 

skip: 

mov [rdi],al             ;store ascii code in result variable

inc rdi                  ; point to next byte

dec cx                   ; decrement counter

jnz up1                  ; if not zero jump to repeat

dispmsg result,16        ;call to macro

ret







;when you accept string , length automatically returns in Rax register

;input welcome

; rax -> 0000000000000008

;copy rax to rbx

;rbx = 0000000000000008


; when you wnat to display no on screen you have to convert it from  hex  to ascii format

; hex 0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f

; ascii 30,31,32,33,34,35,36,37,38,39,(3a,3b,3c,3d,3e,3f,40), 41,42,43,44,45



;rbx = 0000000000000008

; we have to convert 0 to 30 and 8 to 38 in rbx

; so final rbx register contents must be 

; 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 38



;algorithm to display result

;1. take cnt value as 16 into cnt variable

;2. move address of "result" variable into rdi

;3. rotate left rbx register by 4 bits

;rbx reg=16 digit number you want to display

;4. move b1 into al 

;5. and al with 0fh

;6 compare al with 09h

;7 if greater add 37h into al

;8. else add 30 h into al

;9. move al into memory location pointed by rdi

;10. increment rdi

;11. loop the statement till count value becomes zero

;12. return from procedure









Write an X86/64 ALP to accept five 64 bit Hexadecimal numbers from user and store them in an array and display the accepted numbers.

 section .data

msg1 db 10,13,"Enter 5 64 bit numbers"

len1 equ $-msg1

msg2 db 10,13,"Entered 5 64 bit numbers"

len2 equ $-msg2


section .bss

array resd 200

counter resb 1


section .text

global _start

_start:


;display

mov Rax,1

mov Rdi,1

mov Rsi,msg1

mov Rdx,len1

syscall


;accept


mov byte[counter],05

mov rbx,00


loop1:

mov rax,0                  ; 0 for read

mov rdi,0                  ; 0 for keyboard   

mov rsi, array             ;move pointer to start of array

add rsi,rbx               

mov rdx,17                  

syscall

          add rbx,17                    ;to move counter

dec byte[counter]

JNZ loop1


;display

mov Rax,1

mov Rdi,1

mov Rsi,msg2

mov Rdx,len2

syscall


;display

mov byte[counter],05

mov rbx,00

loop2: 

mov rax,1                    ;1 for write 

mov rdi, 1                    ;1 for monitor

mov rsi, array                

add rsi,rbx

mov rdx,17                   ;16 bit +1 for enter 

syscall

add rbx,17

dec byte[counter]

JNZ loop2


;exit system call

mov rax ,60

mov rdi,0

syscall


;output

;vacoea@vacoea-Pegatron:~$ cd ~/Desktop

;vacoea@vacoea-Pegatron:~/Desktop$ nasm -f elf64 ass1.asm

;vacoea@vacoea-Pegatron:~/Desktop$ ld -o ass1 ass1.o

;vacoea@vacoea-Pegatron:~/Desktop$ ./ass1


;Enter 5 64 bit numbers12

;23

;34

;45

;56


;Entered 5 64 bit numbers12

;23

;34

;45

;56


Monday, March 1, 2021

Write an X86/64 ALP to accept a string and to display its length.

 ;String length in Assembly Lanuguage


;macros begin

%macro write 2    ;will be used to write on the screen

mov rax,01h

mov rdi,0h

mov rsi,%1

mov rdx,%2

syscall

%endmacro


%macro read 2    ;will be used to read from the screen

mov rax,0h

mov rdi,1h

mov rsi,%1

mov rdx,%2

syscall

%endmacro


;macros end


section .data



msg2: db "Enter the string ",10

len2: equ $-msg2

msg3 : db "The length of the string is "

len3: equ $-msg3


section .bss


orgstr resb 50  ;original string

wordlen resb 1  ;length of the string

ascii resb 2  ;len in ascii

count resb 1


section .text

global _start:

_start:

write msg2,len2   ;display message



length:   ;the length option


mov al,0  ;initialize al with zero

read orgstr,50

mov byte[wordlen],al

dec byte[wordlen] ;now len has the length of the string without the null character

mov esi,wordlen

mov edi,ascii

mov byte[count],2

mov al,byte[esi]

loop:

rol al,04

mov bl,al

and bl,0Fh

cmp bl,09h

jbe nocorrection

add bl,7h

nocorrection:

add bl,30h

mov byte[edi],bl

inc edi

dec byte[count]

jnz loop


write ascii,2





exit:   ;to exit from the program

mov rax,60

mov rdx,0h

syscall






Write an X86/64 ALP to accept five 64 bit Hexadecimal numbers from user and store them in an array and display the accepted numbers.

 msg1 db "Enter 5 64-bit numbers ",10,13

len1 equ $-msg1


msg2 db "Entered 5 64-bit numbers are ",10,13

len2 equ $-msg2


section .bss

array resb 120

count resb 1


section .text

global _start

_start:


;logic to read 5 64-bit numbers


mov bh,05        ; count is in bh

mov rbx,00      ; array index


up:  mov rax,00

        mov rdi,00

        mov rsi,array

        add rsi,rbx

        mov rdx,17

        syscall

        add rbx,17

        dec byte[count]  ; dec count

        jnz up                  ; check count is 0 or not using zero flag i;



mov byte[count],05       ; count is in bh

mov rbx,00                     ;array index


up1: mov rax,01

        mov rdi,01

        mov rsi,array

        add rsi,rbx

        mov rdx,17

        syscall

        add rbx,17

        dec byte[count]      ; dec count

        jnz up1                    ; check count is 0 or not using zero flag i;



;exit syscall

mov rax, 60

mov rdi,00

syscall

Sunday, February 9, 2020

Write X86/64 ALP to switch from real mode to protected mode and display the values of GDTR, LDTR, IDTR, TR and MSW Registers.


Protected Mode System registers
GDT: Global Descriptor Table
IDT: Interrupt Descriptor Table
LDT: Local Descriptor Table
TR: Task Register



MSW: Machine Status Word
PE: Protection enabled bit. When it is set it is in Protected mode otherwise it is in real mode


Program: registers.asm

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

Section .data
title: db 0x0A,"----Assignment 6-----", 0x0A
title_len: equ $-title
regmsg: db 0x0A,"***** REGISTER CONTENTS *****"
regmsg_len: equ $-regmsg
gmsg: db 0x0A,"Contents of GDTR : "
gmsg_len: equ $-gmsg
lmsg: db 0x0A,"Contents of LDTR : "
lmsg_len: equ $-lmsg
imsg: db 0x0A,"Contents of IDTR : "
imsg_len: equ $-imsg
tmsg: db 0x0A,"Contents of TR : "
tmsg_len: equ $-tmsg
mmsg: db 0x0A,"Contents of MSW : "
mmsg_len: equ $-mmsg
realmsg: db "---- In Real mode. ----"
realmsg_len: equ $-realmsg
protmsg: db "---- In Protected Mode. ----"
protmsg_len: equ $-protmsg
cnt2:db 04H
newline: db 0x0A

Section .bss
g: resd 1
resw 1
l: resw 1
idtr: resd 1
resw 1
msw: resd 1

tr: resw 1
value :resb 4

Section .text
global _start
_start:
scall 1,1,title,title_len
smsw [msw]
mov eax,dword[msw]
bt eax,0
jc next
scall 1,1,realmsg,realmsg_len
jmp EXIT
next:
scall 1,1,protmsg,protmsg_len

 scall 1,1, regmsg,regmsg_len
;printing register contents
scall 1,1,gmsg,gmsg_len
SGDT [g]
mov bx, word[g+4]
call HtoA
mov bx,word[g+2]
call HtoA
mov bx, word[g]
call HtoA

;--- LDTR CONTENTS----t find valid values for all labels after 1001 passes, giving up.

scall 1,1, lmsg,lmsg_len
SLDT [l]
mov bx,word[l]
call HtoA

;--- IDTR Contents -------
scall 1,1,imsg,imsg_len
SIDT [idtr]
mov bx, word[idtr+4]
call HtoA
mov bx,word[idtr+2]
call HtoA
mov bx, word[idtr]
call HtoA

;---- Task Register Contents -0-----
scall 1,1, tmsg,tmsg_len
mov bx,word[tr]
call HtoA

;------- Content of MSW ---------
scall 1,1,mmsg,mmsg_len
mov bx, word[msw+2]
call HtoA
mov bx, word[msw]
call HtoA
scall 1,1,newline,1
EXIT:
mov rax,60
mov rdi,0
syscall

;------HEX TO ASCII CONVERSION METHOD ----------------
HtoA: ;hex_no to be converted is in bx //result is stored in rdi/user defined variable
mov rdi,value
mov byte[cnt2],4H
aup:
rol bx,04
mov cl,bl
and cl,0FH
cmp cl,09H
jbe ANEXT
ADD cl,07H
ANEXT:
add cl, 30H
mov byte[rdi],cl
INC rdi
dec byte[cnt2]
JNZ aup
scall 1,1,value,4
ret

OUTPUT


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