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

Linux 如何在NASM中打印64位数字?,linux,assembly,nasm,x86-64,Linux,Assembly,Nasm,X86 64,我正在编写一个子程序,它应该打印rdi中传递给它的任何东西的十进制值。它适用于每一个可以用32位表示的数字。一旦涉及到64位值,就会出现故障 如果我将4294967295或00000000000000000000000000111111111111111111111B作为参数传递,它将按预期打印。但如果我这样做了 mov rdi, 4294967295 inc rdi call Print_Unsinged 我得到了错误的结果(确切地说是X96) 我用这种方式检查参数的大小: mov rbx,

我正在编写一个子程序,它应该打印rdi中传递给它的任何东西的十进制值。它适用于每一个可以用32位表示的数字。一旦涉及到64位值,就会出现故障

如果我将4294967295或00000000000000000000000000111111111111111111111B作为参数传递,它将按预期打印。但如果我这样做了

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。因此,打印的第一个字符最终是垃圾,而其余数字打印得很好。请看第一个代码片段:我希望参数值为00000000000000000000000000000000000000000000000000b,然后这将触发跳到isQword,因为在清除ebx之后,rbx将设置一个位。但是没有,这个值一直过滤到isByte并打印“X96”


我想不出来,有人能帮忙吗?

这个问题已经解决了,谢谢

我的代码无法检测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

这已经解决了,谢谢

我的代码无法检测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

32位操作会自动将前32位归零,因此测试失败<代码>shr rbx,32;jnz isQword是另一种选择。您的代码的其余部分在哪里?这可能是一个好问题。它刷新了Linux标签。您需要显示用于打印64位寄存器的代码;不是用于检查大小的代码段。您提供的代码中似乎也存在断开连接的情况。您可以在
rdi
中显示值,但随后开始在
rax
中对值进行操作
rbx
可能应该保留,因为它在很多代码中用于全局偏移表(GOT)。问题是检测大小,其余代码到目前为止是不相关的。打印输出是错误的,因为它进入了64位值的32位情况。至于保存rbx,由于我们没有看到完整的代码,它可能会被很好地保存下来。此外,如果您不与其他代码进行互操作,则不需要遵循ABI。@jww:
rbx
在x86-64 SysV ABI中保留调用,但它不用于GOT。64位代码对GOT使用RIP相对寻址。您正在考虑i386 SysV ABI如何使用
ebx
作为PIC代码中的GET指针。32位操作会自动将前32位归零,因此测试失败<代码>shr rbx,32;jnz isQword是另一种选择。您的代码的其余部分在哪里?这可能是一个好问题。它刷新了Linux标签。您需要显示用于打印64位寄存器的代码;不是用于检查大小的代码段。您提供的代码中似乎也存在断开连接的情况。您可以在
rdi
中显示值,但随后开始在
rax
中对值进行操作
rbx
可能应该保留,因为它在很多代码中用于全局偏移表(GOT)。问题是检测大小,其余代码到目前为止是不相关的。打印输出是错误的,因为它进入了64位值的32位情况。至于保存rbx,由于我们没有看到完整的代码,它可能会被很好地保存下来。此外,如果您不与其他代码进行互操作,则不需要遵循ABI。@jww:
rbx
在x86-64 SysV ABI中保留调用,但它不用于GOT。64位代码对GOT使用RIP相对寻址。您正在考虑i386 SysV ABI如何使用
ebx
作为PIC代码中的get指针。