Advertisement

HEX to BCD conversion and BCD to HEX in NASM

Write a switch case driven X86/64 ALP to convert 4-bit HEX to 5-bit BCD and 5-bit BCD to 4-bit HEX.

 


%macro print 2			;Macro for printing 
	mov rax, 1			;rax = 1 for sys_write	
	mov rdi, 1			;unsigned int file descriptor
	mov rsi, %1			;Buffer address
	mov rdx, %2			;Buffer length
	syscall				;Makes system call
%endmacro

%macro input 2			;Macro for reading 
	mov rax, 0			;rax = 0 for sys_read
	mov rdi, 0			;unsigned int file descriptor
	mov rsi, %1			;Buffer address
	mov rdx, %2			;Buffer length
	syscall				;Makes system call
%endmacro

section .data			;For declaring initialized data
	
	mssg db "Write a switch case driven X86/64 ALP to convert 4-bit HEX to 5-bit BCD and 5-bit BCD to 4-bit HEX."
	mssg_len:equ $ - mssg					
	mssg_name db "AMAN THAKUR 3205"		;Initialising mssg_name 
	mssg_name_len: equ $-mssg_name	
			
	mssg_sel db "--> Select an option from the menu : "
	mssg_sel_len: equ $ - mssg_sel
	mssg_menu db "--> Menu :", 10, "1. HEX to BCD", 10, "2. BCD to HEX", 10, "3. Exit", 10
	mssg_menu_len: equ $ - mssg_menu
	
	;===================Messages printed during input================================= 
	mssg1 db "Enter your 4-digit Hex number : "			
	mssg1_len: equ $-mssg1		
	mssg2 db "Enter your 5-digit BCD number : "		
	mssg2_len: equ $-mssg2
	
	;===================Messages printed during display of result=====================
	mssg_hex db "Given number in HEX form : "
	mssg_hex_len: equ $-mssg_hex
	mssg_bcd db "Given number in BCD form : "
	mssg_bcd_len: equ $-mssg_bcd
	
	mssg_error db "Error!!"				
	mssg_error_len:equ $-mssg_error			
	mssg0 db "Invalid Option!"	
	mssg0_len: equ $-mssg0
	space db " "	
	newline db 10						
	
section .bss			;For declaring variables.
	bcd resb 6			;Reserving 6 Byte.
	hex resb 5			;Reserving 5 Byte.
	temp resb 4			;Reserving 4 Byte.
	choice resb 2	
	
section .text			;Actual code is present.
	global _start		;has to be declared for linker(ld).
	_start: 			;tells linker entry point.
	
	print mssg, mssg_len						;Problem Statement.
	print newline, 1				
	print mssg_name, mssg_name_len				;Name and roll number.
	print newline, 1
	
	menu:
		
		print mssg_menu, mssg_menu_len			;Printing menu
		print newline, 1
		print mssg_sel, mssg_sel_len			;Choosing option
		input choice, 2
		
		case_1:
			cmp byte[choice], 31h		
			jne case_2
			call HEXtoBCD						;Calling HEXtoBCD Procedure when choice is 1
			jmp menu
		case_2:	
			cmp byte[choice], 32h
			jne case_3
			call BCDtoHEX						;Calling BCDtoHEX Procedure when choice is 2
			jmp menu
		case_3:
			cmp byte[choice], 33h
			je Exit			;Exiting when choice is 1
			print mssg0, mssg0_len
			print newline, 1
			jmp menu
			
	Exit:
	mov rax, 60									;rax = 60 for sys_exit.
	mov rdi, 0
	syscall
	err:
		print mssg_error, mssg_error_len		;Error mssg for invalid input.
		print newline, 1
		mov rax, 60				
		mov rdi, 0
		syscall
	
	
HEXtoBCD:
	print mssg1, mssg1_len				
	input hex, 5								;Input in hex form
	call ascii_hex								;Converting ascii to hex
												;Hex value got stored in rbx
	mov ax, bx									;Storing hex value in rax
	mov bx, 0Ah									;Storing 10 in bx for division
	mov rcx, 5
	mov rdi, bcd+4								;Pointing to last index of bcd to traverse in reverse order

	next_itr:
		mov rdx, 0								;Making rdx 0 as dividend is rdx:rax
		div rbx									;This divides rdx:rax by rbx
		add dl, 30h								;dl stores remainder, thus we converting it into ascii
		mov [rdi], dl							;And add to bcd 
		dec rdi									;Moving to previous index
	loop	next_itr
	
	print mssg_bcd, mssg_bcd_len				;Printing messg for bcd
	print bcd, 5								;Required bcd output
	print newline, 1
	ret

BCDtoHEX:
	print mssg2, mssg2_len				
	input bcd, 6								;Input in bcd form
	
	mov rcx, 5									;To iterate over all elements of bcd
	mov rdi, bcd								;Point to first element of bcd
	mov ax, 0									;Making ax equal to zero
	mov bl, 10									;Moving 10 for multiplication
	
	next1_itr:
		mul bl									;multiplying ax, 10
		mov dx, 0								;Clearing dx
		mov dl, [rdi]							;Moving char pointed by rsi to dl
		sub dl, 30h								;Ascii to hex
		add ax, dx								;Adding dx to ax
		inc rdi									;Moving to next index
	loop 	next1_itr
		
		mov bx, ax
		print mssg_hex, mssg_hex_len			;Printing messg for hex
		call display							;Required hex output
		print newline, 1
	ret
	
	
ascii_hex:
	mov rcx, 4  					
	mov rsi, hex								;rsi points to num1
	mov rbx, 0 					
	next:						
		rol bx, 4								;Rotating by 4 bits to left, 0Fh -> F0h
		mov al, [rsi]							;Assigning [rsi] to al
		
		cmp al, 2Fh 							;Checking For Error
		jbe err									;Case: al < 30h (0)
		cmp al, 47h	
		jge err									;Case: al > 46h  (F)
		cmp al, 39h				
		jle ELSE								;Case: al <= 39h (9), No Error
		cmp al, 40h				
		jle err									;Case al > 39(9) and al < 41(A)
		
		ELSE:
							
		cmp al, 39h								;Here we convert ascii to hex
		jbe  sub30h								;If al <= 39h (9), subtract 30h
		sub al, 7h								;Else subtract 37h
		sub30h:
			sub al, 30h							;Subtracting 30h from al
		add bl, al				
		inc rsi				
		dec rcx				
	jnz next
	
	ret 										;Return


display:
	mov rcx, 4					
	mov rsi, temp								;rsi points to len
	next1:	
		rol bx, 4								;rotating by 4 bits to left
		mov al, bl				
		and al, 0Fh								;To get only last digit, eg. 5Ah & 0Fh = 0Ah
		cmp al, 9h								;Case : al <= 9h (9)
		jbe add30h								;If True add 30h
		add al, 7h								;Else add 37h

		add30h:
			add al, 30h							;Adding 30h to al
		mov [rsi], al							;Storing al in temp
		inc rsi				
		dec rcx				
	jnz next1
	
	print temp, 4								;Printing number in ascii
	ret											;Return

Post a Comment

0 Comments