简体   繁体   中英

How to print a 64 bit number in NASM?

I'm writing a subroutine that's supposed to print the decimal value of whatever gets passed to it in rdi. It works great for every number that can be represented with 32 bits. As soon as 64 bit values get involved things break down.

if I pass 4294967295 or 0000000000000000000000000000000011111111111111111111111111111111b as an argument it prints as expected. But if I do

mov rdi, 4294967295
inc rdi
call Print_Unsinged

I get the wrong result (X96 to be exact).

I'm checking the size of the argument this way:

mov rbx, rax ; rax has the orginal arg at this point
xor ebx, eax
cmp rbx, 0
jne isQword

mov ebx, eax
xor bx, ax
cmp ebx, 0
jne isDword

cmp ah, 0
jne isWord

jmp isByte

What ends up happening is that a value that should have bits beyond ebx set and should be jumping to isQword jumps to isDword instead. So the first character printed ends up being garbage while the rest of the number prints fine. Look at the first code snippet: I would expect the argument value to be 0000000000000000000000000000000100000000000000000000000000000000b, and then that would trigger a jump to isQword because rbx would have a bit set after ebx was cleared. But no, this value filters all the way down to isByte and prints "X96".

I can't figure this out, can anyone help?

This has been resolved, thank you!

the reason my code could not detect a 64 bit value (as someone pointed out) is that doing a 32 bit operation on a register clears the upper 32 bits of that register.

; rax has the orginal rdi argument at this point in the code
mov rbx, rax 
xor ebx, eax ; this clears the upper 32 bits of rbx
cmp rbx, 0 ; these are equal
jne isQword ; so we don't get to isQword when we should

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM