如何在x86程序集中将64位数转换为字符串?

时间:2016-06-07 21:12:50

标签: assembly x86 att

我正在寻找一种方法,使用32位系统将64位数转换为字符串(可能反过来)。我不是要求代码,只是要求一些想法。

1 个答案:

答案 0 :(得分:3)

唯一困难的部分是在32位机器上将64位数除以10。其他所有内容都与数字适合单个寄存器的正常情况非常相似。

通常你可以查看gcc输出以获取有关如何在asm中执行操作的提示,但在这种情况下它是just calls the __udivdi3 libgcc helper function:/

如果您只是将此作为学习练习,那么您可能只需要查找扩展精度div算法并使用它。 Here's one,来自本书,使用英特尔语法和16位操作。变量名是清楚的,并且有解释性文本,因此您应该能够为32位重新实现它。谷歌在该短语上获得更多点击量,和/或查看libgcc源代码。

另见implementing school-like division on 32bit chunks on x86

如果您要实现此功能(用于高性能):

请记住,x86的div指令执行64b / 32b - > 32b除法(但如果商出溢32位寄存器则出现故障)。所以你可以检查你的高dword的低位是否足够小,如果是这样,你只需要一个分区来获得高位数。

只要您的数字足够小以除以单个div,就会突破扩展精度循环并使用每个数字div

这可能只需要一次迭代就可以减少到32位数。此时,您可以使用乘法逆来除以10:

// from the godbolt link: gcc5.3 -O3 -m32
uint32_t div10_u32(uint32_t x) { return x/10; }
    movl    $-858993459, %edx     # 0xcccccccd
    movl    %edx, %eax            # gcc is dumb: no need for this mov.  clang avoids it
    mull    4(%esp)
    movl    %edx, %eax
    shrl    $3, %eax
    ret

注意这是如何使用全乘的结果的高半部分(32bx32b-> 64b)。

使用乘法反转完成整个事情可能会更快,即使这意味着做64 x 64b - > 128b乘以32位机器。整数除法很慢,几乎没有流水线,但是integer mul is very fast on Intel CPUs

AVX512-DQ adds a 64x64 -> 64b low multiply instruction,但这不适用于扩展精度。 AVX512-IFMA增加了52bx52b低和高乘法指令,因此在几年内可能值得拥有一个代码路径(在AVX512-IFMA的硬件上运行32位二进制文​​件),当你的数字的前64-52位是全零。