I am new to NASM and am trying to convert a 16-bit binary to decimal.
the code goes like this:
extern printf
SECTION .data
fmt: db "The resultant BCD is: ", 0
fmtshort: db "%lu ", 0
binary: dq 1010 ; 16 bit binary number (8 byte int) = 1001101010011010
msb: dq 0 ; most significant bit size int msv = 0 (initially)
divider: dq 1 ; used to isolate the msb of the decimal;
SECTION .text ; code section
global main
main:
push rbp ; base pointer
mov rcx,[binary] ; loading it into binary value
mov r14,0 ; decimal(initially) = 0;
mov r13,0 ; counter(i) = 0;
mov r15,0 ; r15 = 0;
mov rdi,fmt ; storing format in the 1st register
call printf ; calling printf
jmp getFromBinary ; Jump to condition first
cgetFromBinary:
mov rdx,0
mov rax,rcx
mov rbx,10
div rbx
mov rcx,rax ; remainder: rdx, quotient: r11 <- rax
mov rax,r13 ; rax = i
mov r12,1 ; result of 2^i
jmp loop1 ; calculate 2^i
cloop1:
imul r12,2 ; multiply r12 *= 2
dec rax ; rax--
loop1:
cmp r15,rax ; 0 < rax?
jl cloop1 ; jump if met
imul rdx,r12 ; multiply remainder *= 2^i
add r14,rdx ; add decimal += remainder
inc r13 ; i++
getFromBinary:
cmp rcx,0 ; is binary == 0?
jnz cgetFromBinary ; jump if condition is met
mov rdi,fmtshort ; store the format
mov rsi,r14 ; store the 1st printf var
call printf ; call printf
ending:
pop rbp ; pop the stack
mov rax,0 ; exit code
ret ; return to OS from main
So far, I've only done it to the part of converting it to decimal and I noticed rcx has its value refreshed or reset to 0 on entering a new label "getFromBinary" as seen in gdb:
Breakpoint 1, main () at bcd.asm:16
16 push rbp ; base pointer
(gdb) n
17 mov rcx,[binary] ; loading it into binary value
(gdb) n
18 mov r14,0 ; decimal(initially) = 0;
(gdb) p (int)$rcx
$1 = 1010
(gdb) n
19 mov r13,0 ; counter(i) = 0;
(gdb) n
20 mov r15,0 ; r15 = 0;
(gdb) n
21 mov rdi,fmt ; storing format in the 1st register
(gdb) n
22 call printf ; calling printf
(gdb) n
23 jmp getFromBinary ; Jump to condition first
(gdb) n
getFromBinary () at bcd.asm:46
46 cmp rcx,0 ; is binary == 0?
(gdb) n
47 jnz cgetFromBinary ; jump if condition is met
(gdb) n
49 mov rdi,fmtshort ; store the format
(gdb) p (int)$rcx
$2 = 0
How can i use rcx in different labels?
EDIT: Tinkering with the code, I was able to solve it by using the variable itself:
extern printf
SECTION .data
fmt: db "The resultant BCD is: ", 0
fmtshort: db "%lu ", 0
binary: dq 1001101010011010 ; 16 bit binary number (8 byte int) = 1001101010011010
msb: dq 0 ; most significant bit size int msv = 0 (initially)
divider: dq 1 ; used to isolate the msb of the decimal;
SECTION .text ; code section
global main
main:
push rbp ; base pointer
mov rcx,[binary] ; loading it into binary value
mov r14,0 ; decimal(initially) = 0;
mov r13,0 ; counter(i) = 0;
mov r15,0 ; r15 = 0;
mov rdi,fmt ; storing format in the 1st register
call printf ; calling printf
jmp getFromBinary ; Jump to condition first
cgetFromBinary:
mov rdx,0
mov rax,[binary]
mov rbx,10
div rbx
mov [binary],rax ; remainder: rdx, quotient: r11 <- rax
mov rax,r13 ; rax = i
mov r12,1 ; result of 2^i
jmp loop1 ; calculate 2^i
cloop1:
imul r12,2 ; multiply r12 *= 2
dec rax ; rax--
loop1:
cmp r15,rax ; 0 < rax?
jl cloop1 ; jump if met
imul rdx,r12 ; multiply remainder *= 2^i
add r14,rdx ; add decimal += remainder
inc r13 ; i++
getFromBinary:
mov rcx,[binary]
cmp rcx,0 ; is binary == 0?
jnz cgetFromBinary ; jump if condition is met
mov rdi,fmtshort ; store the format
mov rsi,r14 ; store the 1st printf var
call printf ; call printf
ending:
pop rbp ; pop the stack
mov rax,0 ; exit code
ret ; return to OS from main
But the question still remains as to how can i use the register itself in different labels?