首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C:-O3的奇怪标签行为?

C:-O3的奇怪标签行为?
EN

Stack Overflow用户
提问于 2020-07-06 11:25:50
回答 1查看 113关注 0票数 0

给定此代码(最小的示例;其中没有更深层次的含义):

代码语言:javascript
复制
#include <stdio.h>

int main() {
    start:
    asm volatile(
        ".code64\n\t"
        "push %rax\n\t"
        "pop %rax"
    );
    end:
    printf("%ld\n", (const char *)&&end - (const char *)&&start);
}

我们通过执行gcc -O3 -S dummy.c -o -来获得汇编程序代码。正如人们所看到的,这些行包括:

代码语言:javascript
复制
        subq    $8, %rsp
        .cfi_def_cfa_offset 16
#APP
# 5 "dummy.c" 1
        .code64
        push %rax
        pop %rax
# 0 "" 2
#NO_APP
        leaq    .L2(%rip), %rax

这实际上意味着最初的汇编程序代码仍然在二进制中(这是预期的)。

但是如果程序被执行,那么它输出0。这基本上意味着开始标签等于结束标签。另一方面,如果程序是用-O0编译的,它会输出2。

为什么即使gcc -O3 dummy.c && ./a.out包含汇编程序代码也要输出0?

谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-06 13:55:47

请参见GCC虫40078,特别是其中的评论1

如果程序中没有正常使用<...>标签,则可以移动它们。标签的<...>地址只为计算的gotos和任何其他用途而设计,导致它们的放置行为不明确。

还有一条评论认为GCC的asm goto功能(自4.5版起)可能会对记者有所帮助。

事实上,asm goto可以帮助您修复标签的位置。我想asm goto是标签的“正常用途”之一。请参阅下面的示例。请注意我是如何使用asm goto作为一个单独的语句的,因为后面的“有用”语句有一个输出,而asm goto语句却不能这样做。

代码语言:javascript
复制
#include <stdio.h>

int main()
{
start:
    asm goto(""::::start,end);

    unsigned random=0;
    asm volatile("rdrand %0\n" : "=r"(random));
end:
    printf("Random number: %u; label difference: %ld\n",
           random, (long)(&&end - &&start));
}

在网上玩吧!

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62755027

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档