187 lines
6.3 KiB
NASM
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
|