Microprocessor/Codes/Practical-5.2 (add and shift method).asm
2024-06-10 11:23:57 +05:30

187 lines
6.3 KiB
NASM

; THIS CODE HAS BEEN TESTED AND IS FULLY OPERATIONAL.
; Problem Statement: Write X86/64 ALP to perform multiplication of two 8-bit hexadecimal numbers. Using add and shift method. (Use of 64-bit registers is expected).
; Code from Microprocessor (SPPU - Second Year - Computer Engineering - Content) repository on KSKA Git: https://git.kska.io/sppu-se-comp-content/Microprocessor/
; BEGINNING OF CODE
%macro dispmsg 2 ;macro for display
mov rax,1 ;standard ouput
mov rdi,1 ;system for write
mov rsi,%1 ;display message address
mov rdx,%2 ;display message length
syscall ;interrupt for 64-bit
%endmacro ;close macro
%macro exitprog 0 ;macro for exit
mov rax,60 ;system for exit
mov rdx,0
syscall ;interrupt for 64-bit
%endmacro ;close macro
%macro gtch 1 ;macro for accept
mov rax,0 ;standard input
mov rdi,0 ;system for read
mov rsi,%1 ;input the message
mov rdx,1 ;message length
syscall ;interrupt for 64-bit
%endmacro ;close macro
;------------------------------
section .data
nwline db 10
m0 db 10,10,"Program to multiply two numbers using successive addition and add-and-shift method"
l0 equ $-m0
m1 db 10,"1. Add-and-Shift method",10,"2. Exit",10,10, "Choose an option (1/2 <ENTER>): "
l1 equ $-m1
m2 db 10,"Enter multiplicand (2 digit HEX no): "
l2 equ $-m2
m3 db 10,"Enter multiplier (2 digit HEX no): "
l3 equ $-m3
m4 db 10,"Multiplication is: "
l4 equ $-m4
;------------------------------
;------------------------------
section .bss
mcand resq 1 ;reserve 1 quad for multiplicand
mplier resq 1 ;reserve 1 quad for multiplier
input resb 1 ;reserve 1 byte for input
output resb 1 ;reserve 1 byte for output
choice resb 1 ;reserve 1 byte for choice
;------------------------------
;------------------------------
section .text
global _start ;starting of main program
_start :
dispmsg m0,l0 ;displaying the menu
back:
dispmsg m1,l1 ;displaying the first message
gtch input ;to read and discard ENTER key pressed.
mov al, byte[input] ;get choice
mov byte[choice],al
gtch input ;to read and discard ENTER key pressed.
mov al, byte[choice]
cmp al, '1' ;compare contents of al with 1
je shft_add ;if equal the jump to succ_add procedure
cmp al, '2' ;compare the contents of al with 3
jnz back ;if not zero then jump to back
exitprog ;exit program
;------------------------------
;-------- ADD & SHIFT ---------
shft_add: ;shft_add procedure
dispmsg m2,l2 ;Displaying the second message
call getnum ;call getnum procedure
mov [mcand],rax ;mov contents of rax(multiplicand) into mcand buffer
gtch input ;to read and discard ENTER key pressed
dispmsg m3,l3 ;Displaying the third message
call getnum ;call getnum procedure
mov [mplier],rax ;mov contents of rax(multiplier) into mplier buffer
gtch input ;to read and discard ENTER key pressed
mov rax,0 ;clearing the rax register
dispmsg m4,l4 ;displaying the fourth message
mov rax,0 ;clearing the rax register
mov rcx,8 ;taking count of 8 in rcx register
mov dl,[mplier] ;multiplier is 8 bits so it occupies dl
mov bl,[mcand] ;mupltiplicand is 8 bits so it occupies bl
;we will put Q in higher 8 bits of ax (i.e. ah)
;and multipler in lower 8 bits of ax (i.e. al)
mov ah,0 ;clearing ah register
mov al,dl ;ah already 0 and al now contains multiplier
;------------------------------
ll3: ;loop 3 (s3)
mov dh,al ;mov contents of al into dh as dh is used as temporary
and dh,1 ;check d0 bit of multiplier
jz ll8 ;if d0 bit was zero, Z flag will be set (s2)(if zero jmp to loop 8)
add ah, bl ;d0 bit of multiplier is set
;so add multiplicand to Q(add bl into ah)
;------------------------------
ll8: ;loop 8 (s2)
shr ax,1 ;shift both Q (ah) and muplitiplier (al) right 1 bit
dec rcx ;decrement contents of rcx
jnz ll3 ;if not zero then jump to loop 3 (s3)
call disphx16 ;call procedure disphx16
jmp back ;jump to back
;------------------------------
getnum: ;procedure to get a 2 digit hex no from user
; number returned in rax
mov cx,0204h ;02 digits to display and 04 count to rotate
mov rbx,0 ;clearing rbx register
;------------------------------
ll2: ;loop 2
push rcx ;syscall destroys rcx.Rest all regs are preserved
gtch input ;to read and discard ENTER key pressed
pop rcx ;pop the contents of rcx
mov rax,0 ;clearing the contents of rax
mov al,byte[input] ;get choice
sub rax,30h ;subtract 30h from contents of rax
cmp rax,09h ;compare the contents of rax register with 09h
jbe skip1 ;if equal then jump below to skip1 label
sub rax,7 ;subtract 7 from contents of rax register
;------------------------------
skip1: ;skip1 label
shl rbx,cl ;shift multiplicand and count to the left
add rbx,rax ;add contents of rax register to the contents of rbx register
dec ch ;decrement the contents of ch register
jnz ll2 ;if not zero then jump to loop 2
mov rax,rbx ;mov contents of rbx register into rax register
ret ;return
;------------------------------
disphx16: ;Displays a 16 digit hex number passed in rax
mov rbx,rax ;move contents of rax register into rbx register
mov cx,1004h ;16 digits to display and 04 count to rotate
;------------------------------
ll6: ;loop 6
rol rbx,cl ;rotate multiplicand and count to the left
mov rdx,rbx ;mov contents of rbx register into rdx register
and rdx,0fh ;anding contents of rdx register with 0fh
add rdx,30h ;adding contents of rdx register with 30h
cmp rdx,039h ;comparing the contents of rdx register with 39h
jbe skip4 ;if equal then jump below to skip4 label
add rdx,7 ;add 7 to the contents of rdx register
;------------------------------
skip4: ;skip4 label
mov byte[output],dl ;mov contents of dl register into output buffer in bytes
push rcx ;push the contents of rcx register
dispmsg output,1 ;displaying the output
pop rcx ;pop the contents of rcx
dec ch ;decrement the count(contents of ch)
jnz ll6 ;if not zero the jump to loop 6
ret ;return
;------------------------------
; END OF CODE