Last active
March 20, 2017 02:11
-
-
Save AjayKrP/46186ff6a8dee0cb1dca0c62c74163a1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
section .data | |
nline db 10,10 | |
nline_len: equ $-nline | |
msg db 10,10," Hex to BCD & BCD to Hex conversion" | |
db 10,"---------------------------------------------" | |
msg_len: equ $-msg | |
menu db 10,"-----------Menu----------" | |
db 10,"1. Hex to BCD " | |
db 10,"2. BCD to Hex" | |
db 10,"3. Exit " | |
db 10 | |
db 10,"Enter your choice: " | |
menu_len: equ $-menu | |
h2bmsg db 10,"Hex to BCD " | |
db 10,"Enter 4-digit Hex number: " | |
h2bmsg_len: equ $-h2bmsg | |
b2hmsg db 10,"BCD to Hex " | |
db 10,"enter 5-digit BCD number: " | |
b2hmsg_len: equ $-b2hmsg | |
hmsg db 10,13,"Equivalent Hex number is: " | |
hmsg_len: equ $-hmsg | |
bmsg db 10,13,"Equivalent BCD number is: " | |
bmsg_len: equ $-bmsg | |
emsg db 10,"You entered Invalid Data!!!",10 | |
emsg_len: equ $-emsg | |
;--------------------------------------------------------------------- | |
section .bss | |
buf resb 6 | |
buf_len: equ $-buf | |
digitcount resb 1 | |
ans resw 1 | |
char_ans resb 4 | |
;--------------------------------------------------------------------- | |
;macros as per 64-bit convensions | |
%macro print 2 | |
mov rax,1 ; Function 1 - write | |
mov rdi,1 ; To stdout | |
mov rsi,%1 ; String address | |
mov rdx,%2 ; String size | |
syscall ; invoke operating system to WRITE | |
%endmacro | |
%macro read 2 | |
mov rax,0 ; Function 0 - Read | |
mov rdi,0 ; from stdin | |
mov rsi,%1 ; buffer address | |
mov rdx,%2 ; buffer size | |
syscall ; invoke operating system to READ | |
%endmacro | |
%macro exit 0 | |
print nline, nline_len | |
mov rax, 60 ; system call 60 is exit | |
xor rdi, rdi ; we want return code 0 | |
syscall ; invoke operating system to exit | |
%endmacro | |
;--------------------------------------------------------------- | |
section .text | |
global _start | |
_start: | |
print msg,msg_len | |
print menu, menu_len | |
read buf,2 ; choice + enter | |
mov al,[buf] | |
c1: cmp al,'1' | |
jne c2 | |
call hex_bcd | |
jmp _start | |
c2: cmp al,'2' | |
jne c3 | |
call bcd_hex | |
jmp _start | |
c3: cmp al,'3' | |
jne err | |
exit | |
err: print emsg,emsg_len | |
jmp _start | |
;------------------------------------------------------------------ | |
hex_bcd: | |
print h2bmsg, h2bmsg_len | |
call accept_16 | |
mov ax,bx | |
mov rbx,10 | |
back: | |
xor rdx,rdx | |
div rbx | |
push dx | |
inc byte[digitcount] | |
cmp rax,0h | |
jne back | |
print bmsg, bmsg_len | |
print_bcd: | |
pop dx | |
add dl,30h ; possible digits are 0-9 so add 30H only | |
mov [char_ans],dl ; store character in char_ans | |
print char_ans,1 ; print on screen in reverse order | |
dec byte[digitcount] | |
jnz print_bcd | |
ret | |
;------------------------------------------------------------------ | |
bcd_hex: | |
print b2hmsg, b2hmsg_len | |
read buf,buf_len ; buflen = 5 + 1 | |
mov rsi,buf ; load bcd pointer | |
xor rax,rax ; sum | |
mov rbx,10 | |
mov rcx,05 ; digit_count | |
back1: xor rdx,rdx | |
mul ebx ; previous digit * 10 = ans (rax*rbx = rdx:rax) | |
xor rdx,rdx | |
mov dl,[rsi] ; Take current digit | |
sub dl,30h ; accepted digit is Decimal, so Sub 30H only | |
add rax,rdx | |
inc rsi | |
dec rcx | |
jnz back1 | |
mov [ans],ax | |
print bmsg, bmsg_len | |
mov ax,[ans] | |
call display_16 | |
ret | |
;------------------------------------------------------------------ | |
accept_16: | |
read buf,5 ; buflen = 4 + 1 | |
xor bx,bx | |
mov rcx,4 | |
mov rsi,buf | |
next_digit: | |
shl bx,04 | |
mov al,[rsi] | |
cmp al,"0" ; "0" = 30h or 48d | |
jb error ; jump if below "0" to error | |
cmp al,"9" | |
jbe sub30 ; subtract 30h if no is in the range "0"-"9" | |
cmp al,"A" ; "A" = 41h or 65d | |
jb error ; jump if below "A" to error | |
cmp al,"F" | |
jbe sub37 ; subtract 37h if no is in the range "A"-"F" | |
cmp al,"a" ; "a" = 61h or 97d | |
jb error ; jump if below "a" to error | |
cmp al,"f" | |
jbe sub57 ; subtract 57h if no is in the range "a"-"f" | |
error: print emsg,emsg_len ; "You entered Invalid Data!!!" | |
exit | |
sub57: sub al,20h ; subtract 57h if no is in the range "a"-"f" | |
sub37: sub al,07h ; subtract 37h if no is in the range "a"-"f" | |
sub30: sub al,30h ; subtract 30h if no is in the range "0"-"9" | |
add bx,ax ; prepare number | |
inc rsi ; point to next digit | |
loop next_digit | |
ret | |
;------------------------------------------------------------------ | |
display_16: | |
mov rsi,char_ans+3 ; load last byte address of char_ans in rsi | |
mov rcx,4 ; number of digits | |
cnt: mov rdx,0 ; make rdx=0 (as in div instruction rdx:rax/rbx) | |
mov rbx,16 ; divisor=16 for hex | |
div rbx | |
cmp dl, 09h ; check for remainder in RDX | |
jbe add30 | |
add dl, 07h | |
add30: | |
add dl,30h ; calculate ASCII code | |
mov [rsi],dl ; store it in buffer | |
dec rsi ; point to one byte back | |
dec rcx ; decrement count | |
jnz cnt ; if not zero repeat | |
print char_ans,4 ; display result on screen | |
ret | |
;---------------------------------------------------------------- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment