如何在NASM中打印64位数字?

问题描述:

我正在写一个子程序,它应该打印rdi中传递给它的任何数据的十进制值。它适用于每个可以用32位表示的数字。一旦涉及64位值,事情就会崩溃。如何在NASM中打印64位数字?

如果我将4294967295或000000000000000000000000000011111111111111111111111111111111b作为参数传递,按预期打印。但如果我做

mov rdi, 4294967295 
inc rdi 
call Print_Unsinged 

我得到了错误的结果(X96是确切的)。

我检查参数的大小是这样的:

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 

什么最终情况是,应该有超越EBX集位,应该跳到isQword值跳跃而不是isDword。所以打印的第一个字符最终是垃圾,而其余的数字打印罚款。看看第一个代码片段:我期望参数值为0000000000000000000000000000000100000000000000000000000000000000b,然后这将触发跳转到isQword,因为在ebx被清除后,rbx会设置一个位。但是,不,这个值一直过滤到isByte并打印“X96”。

我无法弄清楚,任何人都可以帮忙吗?

+3

32位操作自动清零前32位,所以你的测试失败。 'shr rbx,32; jnz isQword'是另一种选择。 – Jester

+1

你的代码的其余部分在哪里? –

+0

这有可能是一个很好的问题。它为Linux标签刷新。您需要显示您用来打印64位寄存器的代码;而不是用于检查大小的代码段。您提供的代码似乎也存在脱节。你在'rdi'中显示值,然后你开始在'rax'中使用一个值。 'rbx'应该被保留下来,因为它在很多代码中用于全局偏移表(GOT)。 – jww

这个已经解决了,谢谢!

我的代码无法检测到64位值(如某人指出的)的原因是对寄存器执行32位操作会清除该寄存器的高32位。

; 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