Practical No: 01
Aim: 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.
%macro IO 4
mov rax,%1
mov rdi,%2
mov rsi,%3
mov rdx,%4
syscall
%endmacro
section .data
m1 db "Enter the five 64 bit numbers:" ,10 ; 10d -> line feed
l1 equ $-m1
m2 db "The five 64 bit numbers are:" ,10
l2 equ $-m2
m3 db "rahul ghosh 3236" ,10
l3 equ $-m3
m4 db "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." ,10d
l4 equ $-m4
m5 db 10,"Exiting now" ,10
l5 equ $-m5
m6 db "incorrect input error" ,10
l6 equ $-m6
m7 db 10
debug db "debug "
debug_l equ $-debug
time equ 5
size equ 8
section .bss
arr resb 300
_input resb 20
_output resb 20
count resb 1
section .text
global _start
_start:
IO 1,1,m3,l3
IO 1,1,m4,l4
mov byte[count],time ; store time = 5 in count;
mov rbp,arr ;rbp points to begining of arr
IO 1,1,m1,l1
input:
IO 0,0,_input,17
IO 1,1,debug,debug_l
IO 1,1,_input,17
call ascii_to_hex
mov [rbp],rbx ; put the complete summed rbx value to arr[n]
add rbp,size ; move to next value of array 8 -> 4*2 = 1 place -> arr[n+1]
dec byte[count] ; loop
jnz input
mov byte[count],time ; set loop count to 5
mov rbp,arr ;make rbp point to arr beginning
jmp display
display:
mov rax,[rbp] ; address of rbp in rax
call hex_to_ascii
IO 1,1,m7,1
IO 1,1,_output,16
add rbp,size ; move to next value of array 8 -> 4*2 = 1 place arr[n+1]
dec byte[count] ; loop
jnz display
jmp exit
exit:
IO 1,1,m5,l5
mov rax,60
mov rdi,0
syscall
error:
IO 1,1,m6,l6
jmp exit
ascii_to_hex:
mov rsi,_input
Output:-
rahul ghosh 3236
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.
Enter the five 64 bit numbers:
debug 55555555A5555555
debug 44444444F4444434
debug 33333D3333333333
debug 2222222222E22222
debug 1111111111111111
55555555A5555555
44444444F4444434
33333D3333333333
2222222222E22222
1111111111111111
Exiting now
Practical No: 2
Aim: Write an X86/64 ALP to accept a string and to display its length.
%macro print 4 ; simple macro ,
mov rax,%1 ; -> system call number
mov rdi,%2 ; -> file descriptor
mov rsi,%3 ; -> message
mov rdx,%4 ; -> length
syscall
%endmacro
section .data
m1 db "enter string",10 ;10 ->line feed
l1 equ $-m1
m2 db "Entered String is ",10
l2 equ $-m2
m3 db "Length is ",10
l3 equ $-m3
m4 db "Write an X86/64 ALP to accept a string and to display its length" ,10
l4 equ $-m4
section .bss
string resb 50 ;string array of size 50
strl equ $-string
count resb 1
_output resb 16
section .text
global _start
_start:
print 1,1,m4,l4 ; display
print 1,1,m1,l1 ; display
input:
print 0,0,string,strl
mov [count],rax ;count now points to rax
output:
print 1,1,m2,l2 ; display
print 1,1,string,strl
print 1,1,m3,l3 ; display
mov rax,[count] ; value of count passed into rax
call hex_to_dec
print 1,1,_output,16
exit:
mov rax, 60 ; system call for exit
mov rdi, 0 ; exit code 0
syscall
hex_to_dec:
mov rsi,_output+15 ; max size of display , for convinience set to 16 and rsipoints to
output[16]
mov rcx,2 ; loop count , or number of digits displayed , 2 digits (unlikely we will
enter string > 99)(prints preceding zeros otherwise)
letter2:
xor rdx,rdx ; setting rdx to null without setting a null byte (a tip i saw on reddit)
needed to clean dl for use
mov rbx,10 ; conversion base
div rbx ; dividing by conversion base
cmp dl,09h ; comparing 09h with dl , since the division remainder ends up in dx
and since its one digits its in dl
jbe add30 ; if value under in 0-9 , we directly add 30h to get ascii 0-9
add30:
add dl,30h ; adding 30h
mov [rsi],dl ; moving the ascii we generated to rsi
dec rsi ; rsi now points to the next place in display or output[n-1]
dec rcx ; loop
jnz letter2
ret
Output:
Write an X86/64 ALP to accept a string and to display its length
enter string
Entered String is: Yash
Length is: 04
Practical no: 03
Aim: Write an X86/64 ALP to find the largest of given
Byte/Word/Dword/64-bit numbers.
section .data
array db 11h,59h,33h,22h,44h
msg1 db 10,"ALP to find the largest number in an array",10
msg1_len equ $ - msg1
msg2 db 10,"The Array contains the elements : ",10
msg2_len equ $ - msg2
msg3 db 10,10, "The Largest number in the array is : ",10
msg3_len equ $ - msg3
section .bss
counter resb 1
result resb 4
%macro write 2
mov rax,1
mov rdi,1
mov rsi,%1
mov rdx,%2
syscall
%endmacro
section .text
global _start
_start:
write msg1 , msg1_len
write msg2 , msg2_len
mov byte[counter],05
mov rsi,array
next: mov al,[rsi]
push rsi
call disp
pop rsi
inc rsi
dec byte[counter]
jnz next
write msg3 , msg3_len
mov byte[counter],05
mov rsi, array
mov al, 0 ; al is an 8 bit register , al stores max
repeat: cmp al,[rsi] ;cmp opr1 , opr2 : opr1 - opr2
jg skip
mov al,[rsi]
skip: inc rsi
dec byte[counter]
Jnz repeat
call disp
mov rax,60
mov rdi,1
syscall
disp:
mov bl,al ;store number in bl
mov rdi, result ;point rdi to result variable
mov cx,02 ;load count of rotation in cl
up1:
rol bl,04 ;rotate number 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 grater than 39h skip add 37
add al,30h
jmp skip1 ;else add 30
add_37: add al,37h
skip1: mov [rdi],al ;store ascii code in result variable
inc rdi ;point to next byte
dec cx ;decrement the count of digits to display
jnz up1 ;if not zero jump to repeat
write result , 4
ret
Output:
ALP to find the largest number in an array
The Array contains the elements :
1159332244
The Largest number in the array is :
59
[Execution complete with exit code 1]
Practical No: 4
Aim: Write a switch case driven X86/64 ALP to perform 64-bit
hexadecimal arithmetic, operations (+,-,*, /) using suitable macros. Define
procedure for each operation.
%macro IO 4
mov rax,%1
mov rdi,%2
mov rsi,%3
mov rdx,%4
syscall
%endmacro
section .data
m1 db "enter choice (+,-,*, /)" ,10 ; 10d -> line feed
l1 equ $-m1
m2 db "Write a switch case driven X86/64 ALP to perform 64-bit hexadecimal arithmetic
operations (+,-,*, /) using suitable macros. Define procedure for each operation." ,10
l2 equ $-m2
m3 db "rahul ghosh 3236" ,10
l3 equ $-m3
madd db "addition here" ,10
l4 equ $-madd
msub db "subtraction here" ,10
l5 equ $-msub
mmul db "multiplication here" ,10
l6 equ $-mmul
mdiv db "division here" ,10
l7 equ $-mdiv
mspace db 10
m_result db "result is "
m_result_l equ $-m_result
m_qou db "qoutient is "
m_qou_l equ $-m_qou
m_rem db "remainder is "
m_rem_l equ $-m_rem
m_default db "enter correct choice",10
m_default_l equ $-m_default
section .bss
choice resb 2
_output resq 1
_n1 resq 1
_n2 resq 1
temp_1 resq 1
temp_2 resq 1
section .text
global _start
_start:
IO 1,1,m2,l2
IO 1,1,m3,l3
IO 1,1,m1,l1
IO 0,0,choice,2
cmp byte [choice],'+'
jne case2
call add_fun
jmp exit
case2:
cmp byte [choice],'-'
jne case3
call sub_fun
jmp exit
case3:
cmp byte [choice],'*'
jne case4
call mul_fun
jmp exit
case4:
cmp byte [choice],'/'
jne case5
call div_fun
jmp exit
case5:
cmp byte [choice],'a'
jne error
call add_fun
call sub_fun
call mul_fun
call div_fun
jmp exit
error:
IO 1,1,m_default,m_default_l
jmp exit
exit:
mov rax, 60
mov rdi, 0
syscall
add_fun:
IO 1,1,madd,l4
mov qword[_output],0
IO 0,0,_n1,17
IO 1,1,_n1,17
call ascii_to_hex
add qword[_output],rbx
IO 0,0,_n1,17
IO 1,1,_n1,17
call ascii_to_hex
add qword[_output],rbx
mov rbx,[_output]
IO 1,1,mspace,1
IO 1,1,m_result,m_result_l
call hex_to_ascii
ret
sub_fun:
IO 1,1,msub,l5
mov qword[_output],0
IO 0,0,_n1,17
IO 1,1,_n1,17
;IO 1,1,mspace,1
call ascii_to_hex
add qword[_output],rbx
IO 0,0,_n1,17
IO 1,1,_n1,17
;IO 1,1,mspace,1
call ascii_to_hex
sub qword[_output],rbx
mov rbx,[_output]
IO 1,1,mspace,1
IO 1,1,m_result,m_result_l
call hex_to_ascii
ret
mul_fun:
IO 1,1,mmul,l6 ; message
IO 0,0,_n1,17 ; n1 input
IO 1,1,_n1,17
call ascii_to_hex; conversion returns hex value in rbx
mov [temp_1],rbx ; storing hex in temp_1
IO 0,0,_n1,17 ;n2 input
IO 1,1,_n1,17
call ascii_to_hex
mov [temp_2],rbx ; putting hex of n2 in temp_2
mov rax,[temp_1] ; temp_1->rax
mov rbx,[temp_2] ;temp_2->rbx
mul rbx ; multiplication
push rax
push rdx
IO 1,1,mspace,1
IO 1,1,m_result,m_result_l
pop rdx
mov rbx,rdx; setting rbx value for conversion
call hex_to_ascii
pop rax
mov rbx,rax; setting rbx value for conversion
call hex_to_ascii ; final output
ret
div_fun:
IO 1,1,mdiv,l7
IO 0,0,_n1,17 ; n1 input
IO 1,1,_n1,17
call ascii_to_hex; conversion returns hex value in rbx
mov [temp_1],rbx ; storing hex in temp_1
IO 0,0,_n1,17 ;n2 input
IO 1,1,_n1,17
call ascii_to_hex
mov [temp_2],rbx ; putting hex of n2 in temp_2
mov rax,[temp_1] ; temp_1->rax
mov rbx,[temp_2] ;temp_2->rbx
xor rdx,rdx
mov rax,[temp_1] ; temp_1->rax
mov rbx,[temp_2] ; temp_2->rbx
div rbx ; div
push rax
push rdx
IO 1,1,mspace,1
IO 1,1,m_rem,m_rem_l
pop rdx
mov rbx,rdx
call hex_to_ascii; remainder output
IO 1,1,mspace,1
IO 1,1,m_qou,m_qou_l
pop rax
mov rbx,rax
call hex_to_ascii; quotient output
ret
ascii_to_hex:
mov rsi, _n1
mov rcx, 16
xor rbx, rbx
next1:
rol rbx, 4
mov al, [rsi]
cmp al,47h
jge error
cmp al, 39h
jbe sub30h
sub al, 7
sub30h:
sub al, 30h
add bl, al
inc rsi
loop next1
ret
hex_to_ascii:
mov rcx, 16
mov rsi,_output
next2:
rol rbx, 4
mov al, bl
and al, 0Fh
cmp al, 9
jbe add30h
add al, 7
add30h:
add al, 30h
mov [rsi], al
inc rsi
loop next2
IO 1,1,_output,16
IO 1,1,mspace,1
Ret
Output:
Write a switch case driven X86/64 ALP to perform 64-bit hexadecimal arithmetic
operations (+,-,*, /) using suitable macros. Define procedure for each
operation.
rahul ghosh 3236
enter choice (+,-,*, /)
multiplication here
0000000000000004
0000000000000002
result is 0000000000000000
0000000000000008
[Execution complete with exit code 0]
Practical No: 5
Aim:
section .data
msg : db "1.HEX to BCD ", 0x0A
db "2.BCD to HEX ", 0x0A
db "3.Exit",0x0A
len: equ $-msg
msg1: db "Enter your Choice : "
len1: equ $-msg1
msg2: db "Enter HEX number : "
len2: equ $-msg2
msg3: db "Enter BCD number : "
len3: equ $-msg3
msg4: db "Equivalent BCD number is : "
len4: equ $-msg4
msg5: db "Equivalent HEX number is : "
len5: equ $-msg5
m: db " ",0x0A
l: equ $-m
section .bss
num: resb 6
result: resb 4
ans : resb 4
digitcount : resb 01
choice : resb 02
section .txt
global _start
_start:
menu:
mov rax,1
mov rdi,1
mov rsi,m ;Newline
mov rdx,l
syscall
mov rax,1
mov rdi,1
mov rsi,m ;Newline
mov rdx,l
syscall
mov rax,1
mov rdi,1
mov rsi,msg
mov rdx,len
syscall
mov rax,1
mov rdi,1
mov rsi,msg1
mov rdx,len1
syscall
mov rax,0
mov rdi,0
mov rsi,choice
mov rdx,02
syscall
cmp byte[choice],31H
je case1
cmp byte[choice],32H
je case2
cmp byte[choice],33H
je case3
case3:
mov rax,60
mov rdi,0
syscall
case2:
mov rax,1
mov rdi,1
mov rsi,msg3
mov rdx,len3
syscall
mov rax,0
mov rdi,0
mov rsi,num
mov rdx,6
syscall
xor rax,rax
mov rbx,10
mov rcx,05
up2:
xor rdx,rdx
mul ebx
xor rdx,rdx
mov dl,[rsi]
sub dl,30H
add rax,rdx
inc rsi
dec rcx
jnz up2
mov [result],ax
mov rax,1
mov rdi,1
mov rsi,msg5
mov rdx,len5
syscall
mov ax,[result]
call display
jmp menu
case1:
mov rax,1
mov rdi,1
mov rsi,msg2
mov rdx,len2
syscall
call accept
mov ax,bx
mov rbx,10
back:
xor rdx,rdx
div rbx
push dx
inc byte[digitcount]
cmp rax,0h
jne back
print:
pop dx
add dl,30h
mov [result],dl
mov rax,1
mov rdi,1
mov rsi,result
mov rdx,1
syscall
dec byte[digitcount]
jnz print
jmp menu
accept:
mov rax,0
mov rdi,0
mov rsi,num
mov rdx,5
syscall
xor bx,bx
mov rcx,4
mov rsi,num
next_digit:
rol bx,04
mov al,[rsi]
cmp al,39h
jbe sub30
sub al,7h
mov rdx,4
syscall
ret
Output:
;1.HEX to BCD
;2.BCD to HEX
;3.Exit
;Enter your Choice : 1
;Enter HEX number : ABCD
;43981
;
;1.HEX to BCD
;2.BCD to HEX
;3.Exit
;Enter your Choice : 2
;Enter BCD number : 43981
;Equivalent HEX number is : ABCD
;1.HEX to BCD
;2.BCD to HEX
;3.Exit
;Enter your Choice : 3
Practical No: 6
Aim: Write X86/64 ALP to detect protected mode and display the values of
GDTR, LDTR, IDTR, TR
section .data
nline db 10,10
nline_len: equ $-nline
colon db ":"
rmsg db 10,'Processor is in Real Mode...'
rmsg_len: equ $-rmsg
pmsg db 10,'Processor is in Protected Mode...'
pmsg_len: equ $-pmsg
gmsg db 10,"GDTR (Global Descriptor Table Register) :"
gmsg_len: equ $-gmsg
imsg db 10,"IDTR (Interrupt Descriptor Table Register) :"
imsg_len: equ $-imsg
lmsg db 10,"LDTR (Local Descriptor Table Register) : "
lmsg_len: equ $-lmsg
tmsg db 10,"TR (Task Register) :"
tmsg_len: equ $-tmsg
mmsg db 10,"MSW (Machine Status Word) : "
mmsg_len: equ $-mmsg
;---------------------------------------------------------------------
Section .bss
GDTR resw 3 ; 48 bits, so 3 words
IDTR resw 3
LDTR resw 1 ; 16 bits, so 1 word
TR resw 1
MSW resw 1
char_sum resb 4 ; 16-bits, so 4 digits
;---------------------------------------------------------------------
;you can change the macros as per 64-bit convensions
%macro print 2
mov eax, 4
mov ebx, 1
mov ecx, %1
mov edx, %2
int 80h
%endmacro
%macro exit 0
mov eax, 1
mov ebx, 0
int 80h
%endmacro
;---------------------------------------------------------------------
section .text
global _start
_start:
SMSW [MSW]
mov eax,[MSW]
ror eax,1 ; Check PE bit, if 1=Protected Mode, else Real Mode
jc p_mode
print rmsg,rmsg_len
jmp next
p_mode:
print pmsg,pmsg_len
next:
SGDT [GDTR]
SIDT [IDTR]
SLDT [LDTR]
STR [TR]
print gmsg, gmsg_len ;GDTR (Global Descriptor Table Register)
; LITTLE ENDIAN SO TAKE LAST WORD FIRST
mov ax,[GDTR+4] ; load value of GDTR[4,5] in ax
call disp16_proc ; display GDTR contents
mov ax,[GDTR+2] ; load value of GDTR[2,3] in ax
call disp16_proc ; display GDTR contents
print colon,1
mov ax,[GDTR+0] ; load value of GDTR[0,1] in ax
call disp16_proc ; display GDTR contents
print imsg, imsg_len ;IDTR (Interrupt Descriptor Table Register)
mov ax,[IDTR+4]
call disp16_proc
mov ax,[IDTR+2]
call disp16_proc
print colon,1
mov ax,[IDTR+0]
call disp16_proc
print lmsg, lmsg_len ;LDTR (Local Descriptor Table Register)
mov ax,[LDTR+0]
call disp16_proc
print tmsg, tmsg_len ;TR (Task Register)
mov ax,[TR+0]
call disp16_proc
print mmsg, mmsg_len ;MSW (Machine Status Word)
mov ax,[MSW]
call disp16_proc
print nline, nline_len
exit
;--------------------------------------------------------------------
disp16_proc:
mov esi,char_sum+3 ; load last byte address of char_sum buffer in esi
mov ecx,4 ; number of digits
cnt: mov edx,0 ; make rdx=0 (as in div instruction rdx:rax/rbx)
mov ebx,16 ; divisor=16 for hex
div ebx
cmp dl, 09h ; check for remainder in RDX
jbe add30
add dl, 07h
add30:
add dl,30h ; calculate ASCII code
mov [esi],dl ; store it in buffer
dec esi ; point to one byte back
dec ecx ; decrement count
jnz cnt ; if not zero repeat
print char_sum,4 ; display result on screen
ret
Output:
Processor is in Protected Mode...
GDTR (Global Descriptor Table Register) : 00032000:007F
IDTR (Interrupt Descriptor Table Register) : 00000000:0FFF
LDTR (Local Descriptor Table Register) : 0000
TR (Task Register) : 0040
MSW (Machine Status Word) : 0033
Practical No: 7
Aim: Write X86/64 ALP to perform non-overlapped block transfer without
string specific instructions. Block containing data can be defined in the
data segment.
section .data
sourceBlock db 12h,45h,87h,24h,97h
count equ 05
msg db "ALP for non overlapped block transfer using string instructions : ",10
msg_len equ $ - msg
msgSource db 10,"The source block contains the elements : ",10
msgSource_len equ $ - msgSource
msgDest db 10,10,"The destination block contains the elements : ",10
msgDest_len equ $ - msgDest
bef db 10, "Before Block Transfer : ",10
beflen equ $ - bef
aft db 10,10 ,"After Block Transfer : ",10
aftlen equ $ - aft
section .bss
destBlock resb 5
result resb 4
%macro write 2
mov rax,1
mov rdi,1
mov rsi,%1
mov rdx,%2
syscall
%endmacro
section .text
global _start
_start:
write msg , msg_len
write bef , beflen
write msgSource , msgSource_len
mov rsi,sourceBlock
call dispBlock
write msgDest , msgDest_len
mov rsi,destBlock
call dispBlock
mov rsi,sourceBlock
mov rdi,destBlock
mov rcx, count
cld
rep movsb
write aft , aftlen
write msgSource , msgSource_len
mov rsi,sourceBlock
call dispBlock
write msgDest , msgDest_len
mov rsi,destBlock
call dispBlock
mov rax,60
mov rdi,0
syscall
dispBlock:
mov rbp,count
next:mov al,[rsi]
push rsi
call disp
pop rsi
inc rsi
dec rbp
jnz next
ret
disp:
mov bl,al ;store number in bl
mov rdi, result ;point rdi to result variable
mov cx,02 ;load count of rotation in cl
up1:
rol bl,04 ;rotate number 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 grater than 39h skip add 37
add al,30h
jmp skip1 ;else add 30
add_37: add al,37h
skip1: mov [rdi],al ;store ascii code in result variable
inc rdi ;point to next byte
dec cx ;decrement the count of digits to display
jnz up1 ;if not zero jump to repeat
write result , 4
ret
Output:
ALP for non overlapped block transfer using string instructions :
Before Block Transfer :
The source block contains the elements :
1245872497
The destination block contains the elements :
0000000000
After Block Transfer :
The source block contains the elements :
1245872497
The destination block contains the elements :
1245872497
[Execution complete with exit code 0]
Practical No: 8
Aim:
section .data
msg db 'Enter two digit Number::',0xa
msg_len equ $-msg
res db 10,'Multiplication of elements is::'
res_len equ $-res
choice db 'Enter your Choice:',0xa
db'1.Successive Addition',0xa
db '2.Add and Shift method',0xa
db '3.Exit',0xa
choice_len equ $-choice
section .bss
num resb 03
num1 resb 01
result resb 04
cho resb 2
section .text
global _start
_start:
xor rax,rax
xor rbx,rbx
xor rcx,rcx
xor rdx,rdx
mov byte[result],0
mov byte[num],0
mov byte[num1],0
mov rax,1
mov rdi,1
mov rsi,choice
mov rdx,choice_len
syscall
mov rax,0 ;; read choice
mov rdi,0
mov rsi,cho
mov rdx,2
syscall
cmp byte[cho],31h ;; comparing choice
je a
cmp byte[cho],32h
je b
jmp exit
a: call Succe_addition
jmp _start
b: call Add_shift
jmp _start
exit:
mov rax,60
mov rdi,0
syscall
convert: ;; ASCII to Hex conversion
xor rbx,rbx
xor rcx,rcx
xor rax,rax
mov rcx,02
mov rsi,num
up1:
rol bl,04
mov al,[rsi]
cmp al,39h
jbe p1
sub al,07h
jmp p2
p1: sub al,30h
p2: add bl,al
inc rsi
loop up1
ret
display: ;; Hex to ASCII conversion
mov rcx,4
mov rdi,result
dup1:
rol bx,4
mov al,bl
and al,0fh
cmp al,09h
jbe p3
add al,07h
jmp p4
p3: add al,30h
p4:mov [rdi],al
inc rdi
loop dup1
mov rax,1
mov rdi,1
mov rsi,result
mov rdx,4
syscall
ret
Succe_addition:
mov rax,1
mov rdi,1
mov rsi,msg
mov rdx,msg_len
syscall
mov rax,0
mov rdi,0
mov rsi,num
mov rdx,3
syscall
call convert
mov [num1],bl
mov rax,1
mov rdi,1
mov rsi,msg
mov rdx,msg_len
syscall
mov rax,0
mov rdi,0
mov rsi,num
mov rdx,3
syscall
call convert
xor rcx,rcx
xor rax,rax
mov rax,[num1]
repet:
add rcx,rax
dec bl
jnz repet
mov [result],rcx
mov rax,1
mov rdi,1
mov rsi,res
mov rdx,res_len
syscall
mov rbx,[result]
call display
ret
Add_shift:
mov rax,1
mov rdi,1
mov rsi,msg
mov rdx,msg_len
syscall
mov rax,0
mov rdi,0
mov rsi,num
mov rdx,3
syscall
call convert
mov [num1],bl
mov rax,1
mov rdi,1
mov rsi,msg
mov rdx,msg_len
syscall
mov rax,0
mov rdi,0
mov rsi,num
mov rdx,3
syscall
call convert
mov [num],bl
xor rbx,rbx
xor rcx,rcx
xor rdx,rdx
xor rax,rax
mov dl,08
mov al,[num1]
mov bl,[num]
p11:
shr bx,01
jnc p
add cx,ax
p:
shl ax,01
dec dl
jnz p11
mov [result],rcx
mov rax,1
mov rdi,1
mov rsi,res
mov rdx,res_len
syscall
;dispmsg res,res_len
mov rbx,[result]
call display
ret
output:
;;Enter your Choice:
;;1.Successive Addition
;;2.Add and Shift method
;;3.Exit
;;1
;;Enter two digit Number::
;;02
;;Enter two digit Number::
;;02
;;Multiplication of elements is::0004Enter your Choice:
;;1.Successive Addition
;;2.Add and Shift method
;;3.Exit
;;2
;;Enter two digit Number::
;;03
;;Enter two digit Number::
;;03
;;Multiplication of elements is::0009Enter your Choice:
;;1.Successive Addition
;;2.Add and Shift method
;;3.Exit
;;3
Practical No: 9
Aim: Write x86 ALP to find the factorial of a given integer number on a
command line by using recursion. Explicit stack manipulation is expected
in the code.
section .data
nummsg db "***Program to find Factorial of a number*** ",10
db "Enter the number : ",
nummsg_len equ $-nummsg
resmsg db "Factorial is : "
resmsg_len equ $-resmsg
thankmsg db 10,"Thank you ",10
thankmsg_len equ $-thankmsg
zerofact db " 00000001 "
zerofactlen equ $-zerofact
;-------------------------.bss section------------------------------
section .bss
dispbuff resb 16
result resb 4
num resb 1
num1 resb 1
numascii resb 3
%macro display 2
mov rax,01
mov rdi,01
mov rsi,%1
mov rdx,%2
syscall
%endmacro
%macro accept 2
mov rax,0
mov rdi,0
mov rsi,%1
mov rdx,%2
syscall
%endmacro
;------------------------.text section -----------------------------
section .text
global _start
_start:
display nummsg,nummsg_len
accept numascii,3 ;accept number from user
call packnum8_proc ;convert number from ascii to hex
mov [num],bl
display resmsg,resmsg_len
mov al,[num] ;store number in accumulator
cmp al,01h
jbe endfact
mov bl,[num]
call proc_fact
mov rbx,rax
call disp64_proc
jmp exit
endfact:
display zerofact,zerofactlen
exit:
display thankmsg,thankmsg_len
mov rax,60
mov rdi,0
syscall
ret
;-------------------------------------------------------------
disp64_proc:
mov rdi,dispbuff ;point esi to buffer
mov rcx,16 ;load number of digits to display
dispup1:
rol rbx,4 ;rotate number left by four bits
mov dl,bl ;move lower byte in dl
and dl,0fh ;mask upper digit of byte in dl
add dl,30h ;add 30h to calculate ASCII code
cmp dl,39h ;compare with 39h
jbe dispskip1 ;if less than 39h akip adding 07 more
add dl,07h ;else add 07
dispskip1:
mov [rdi],dl ;store ASCII code in buffer
inc rdi ;point to next byte
loop dispup1 ;decrement the count of digits to display
;if not zero jump to repeat
display dispbuff,16
ret
;--------------------------------------------------------------------
packnum8_proc:
mov bx,0
mov ecx,02
mov esi,numascii
up1:
rol bl,04
mov al,[esi]
cmp al,39h
jbe skip1
sub al,07h
skip1:
sub al,30h
add bl,al
inc esi
loop up1
ret
;***********************Recursion*************************************
;There are two kinds of recursion: direct and indirect.
;In direct recursion, the procedure calls itself and
;in indirect recursion, the first procedure calls a second
;procedure,which in turn, calls the first procedure.
proc_fact:
cmp bl, 1
jne do_calculation
mov ax, 1
ret
do_calculation:
push rbx
dec bl
call proc_fact
pop rbx
mul bl
ret
Output:
;***Program to find Factorial of a number***
;Enter the number : Factorial is : 0000000000000006
;Thank you
Practical No: 10
Aim: Write an X86/64 ALP password program that operates as follows:
a. Do not display what is actually typed instead display asterisk (“*”).
If the password is correct display, “access is granted” else display “Access
not Granted”
%macro rw 4
mov rax, %1
mov rdi, %2
mov rsi, %3
mov rdx, %4
syscall
%endmacro
section .data
password db "password"
passlen equ $-password
msg1 db "Enter Password:",0ah
len1 equ $-msg1
msg2 db "Password is correct ",0ah
len2 equ $-msg2
msg3 db "Password is Incorrect",0ah
len3 equ $-msg3
section .bss
input resb 50
iplen resb 1
section .text
global _start
_start:
rw 1,1,msg1,len1 ; displaying "Enter Password"
rw 0,0,input,50 ; accpeting input
mov [iplen],al ; storing input length at memory location
mov rsi,password ; moving password to rsi
mov rdi,input ; moving input string to rdi
mov cl,passlen ;
len: cmp byte[iplen],passlen
jne incorrect
mov cl,passlen
up:
mov al,byte[rsi] ; byte by byte comparision of input string and password
cmp al,byte[rdi]
jne incorrect
inc rsi
inc rdi
dec cl
jnz up
rw 1,1,msg2,len2
jmp exit
incorrect:
rw 1,1,msg3,len3
jmp exit
exit:
rw 60,0,0,0
Output:
Enter Password:
Password is correct
[Execution complete with exit code 0]