Microprocessor/Codes/Practical-5.asm

230 lines
9.4 KiB
NASM

; THIS CODE HAS NOT BEEN TESTED AND IS NOT FULLY OPERATIONAL.
; Problem Statement: Write X86/64 ALP to perform multiplication of two 8-bit hexadecimal numbers. Using successive addition and add-and-shift methods. (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/
;------------------------------
%macro print 2
mov rax,1
mov rdi,1
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
%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
%macro exitprog 0 ;macro for exit
mov rax,60 ;system for exit
mov rdx,0
syscall ;interrupt for 64-bit
%endmacro
%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
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. Successive Addition Method",10,"2. Add-and-Shift Method",10,"3. Exit",10,10, "Choose an option (1/2/3 <ENTER>): "
l1 equ $-m1
m2 db 10,"Enter the multiplicand (2 digit HEX no): "
l2 equ $-m2
m3 db 10,"Enter the multiplier (2 digit HEX no): "
l3 equ $-m3
m4 db 10,"Multiplication using Successive Addition Method: "
l4 equ $-m4
m5 db 10,"Multiplication using Add-and-Shift Method: "
l5 equ $-m5
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 succ_add ;if equal the jump to succ_add procedure
cmp al, '2' ;compare the contents of al with 2
je add_shift ;if equal then jump to add_shift procedure
cmp al, '3' ;compare the contents of al with 3
jnz back ;if not zero then jump to back
exitprog ;exit program
;-------- SUCCESSIVE ADDITION METHOD ---------
succ_add: ;successive addition 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
call succ_addition ;call the successive addition method
jmp back ;jump to back
;-------- ADD AND SHIFT METHOD ---------
add_shift: ;add and shift 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 m5,l5 ;displaying the fifth message
call add_and_shift ;call the add-and-shift method
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
succ_addition: ;procedure for successive addition
mov rax,0 ;clearing 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] ;multiplicand is 8 bits so it occupies bl
;we will put Q in higher 8 bits of ax (i.e. ah)
;and multiplier 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 multiplier (al) right 1 bit
dec rcx ;decrement contents of rcx
jnz ll3 ;if not zero then jump to loop 3 (s3)
call dispnum ;call procedure dispnum
ret ;return
add_and_shift: ;procedure for add-and-shift method
mov rax,0 ;clearing 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] ;multiplicand is 8 bits so it occupies bl
;we will put Q in higher 8 bits of ax (i.e. ah)
;and multiplier 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_shift: ;loop 3 (s3) for add-and-shift
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_shift ;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_shift: ;loop 8 (s2) for add-and-shift
shl ax,1 ;shift both Q (ah) and multiplier (al) left 1 bit
dec rcx ;decrement contents of rcx
jnz ll3_shift ;if not zero then jump to loop 3 (s3) for add-and-shift
call dispnum ;call procedure dispnum
ret ;return
dispnum: ;procedure to display the result
mov rbx,rax ;move contents of rax register into rbx register
mov rcx,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