为什么std::print生成的汇编代码中有大量整型常量?

问题描述 投票:0回答:1

我正在玩“你好世界!”在 clang 18.1.0 上使用新的 std::print 函数进行程序时,我注意到有几千行整数常量,如 here on godbolt 所示。它们的目的是什么?为什么它们没有出现在基于

std::cout
的经典“你好世界!”中?

c++ assembly clang++
1个回答
1
投票

你是说像这样的块吗?

.LJTI17_0:
    .long   .LBB17_1-.LJTI17_0
    .long   .LBB17_2-.LJTI17_0
    .long   .LBB17_24-.LJTI17_0

这些是从表到其他标签的 32 位偏移量表,可能用于与位置无关的代码中的

switch
。 标签名称的
JTI
部分大概代表跳转表,I 可能代表间接?

我在

parser<char>
中看到有使用它的代码,例如GCC跳转表初始化代码生成movsxd并添加?

    lea     rdx, [rip + .LJTI29_0]
    movsxd  rcx, dword ptr [rdx + 4*rcx]   # sign-extending load indexing into the table
    add     rcx, rdx                       # add it to the table address
    jmp     rcx                            # to get a jump target

Godbolt 默认情况下会过滤库函数的代码,因此代码是隐藏的,但

std::print
是在标头中定义的,因此它会编译为使用它的编译单元的大量代码。与
<iostream>
不同,
operator<<
的定义仅在库中,不可内联,因此调用方中的 asm 只是对
std::cout
等全局变量的构造函数调用,并且只是普通的函数调用。

我还看到了一些文字整数常量表,例如

std::__1::__extended_grapheme_custer_property_boundary::__entries:
        .long   145
        .long   20485
        .long   22545
        .long   26624
        .long   28945
        .long   260609
        .long   346115
        .long   354305
        .long   356355
        .long   1574642
     ...

std::__1::__width_estimation_table::__entries:
        .long   71303263
        .long   147226625
        .long   147472385
        .long   150618115
        .long   150732800

它们的名称似乎相当不言自明,或者至少足够长,可以在源代码中搜索定义和使用它们的代码。

还有一个适合 32 位的 10 的幂表,其名称表明了用途:

std::__1::__itoa::__pow10_32:
        .long   0
        .long   10
        .long   100
        .long   1000
        .long   10000
        .long   100000
        .long   1000000
        .long   10000000
        .long   100000000
        .long   1000000000

对小表进行二进制或线性搜索可能比实际乘以

x *= 10
来获取要比较的值以查看数字的十进制数字长度更快,特别是在重复使用的情况下。 这就是您可能想要做的事情,这样您就可以在为非 2 的幂碱基生成 LSD 优先时将数字存储到 itoa 输出缓冲区中,并且仍然在已知位置保留第一个数字。 (否则,您可以从缓冲区的末尾开始并进行复制,但是如果您进行宽复制,则会出现存储转发停顿,并且您可能不知道在奇数长度的末尾写入是否安全。请参阅 如何在汇编级编程中打印整数而不使用 c 库中的 printf(itoa,整数到十进制 ASCII 字符串)

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.