为什么不能在多个函数中定义相同的本地标签?

时间:2016-09-20 19:27:25

标签: assembly syntax x86-64 gas

想要在多个功能中定义相同的本地标签:

    .text
    .globl main
func:
    push %rbp
    mov %rsp, %rbp
.a:
    leave
    ret

main:
    push %rbp
    mov %rsp, %rbp
.a:
    leave
    ret

奇怪地得到错误:

$ clang -c main.s
main.s:13:1: error: invalid symbol redefinition
.a:
^

当我使用yasm时,它允许在多个函数中使用相同的本地标签。 你有任何线索吗?

1 个答案:

答案 0 :(得分:4)

与NASM不同,.label在气体语法中不是函数的本地(实际上在非.标签之前)。

.Llabel是一个“本地”符号名称,这意味着它不会出现在符号表中。它在整个文件中仍然可见,因此the GNU as manual不会将其称为本地标签。

是气体语法中的本地标签,但它们不是功能范围的。 (见上面的链接)。你使用前进/后退注释来引用它们,否则它们是数字常量而不是标签。 (例如mov $1, %eax将文字1放入eax,而不是最新1:的地址。

更重要的是,您无法为他们提供有意义的名称,例如.Lcopy_loop.Linput_non_zero。它们在宏定义中或在内联asm中很有用,可能内联到多个位置或由优化器复制。否则有意义的名称应该是首选

func1:
    test
    jcc 1f    # you need the forward/back annotation, otherwise it's an absolute address to jump to.
    ...
1:
    ...
    ret

func2:
    test
    # jcc 1b    # BAD!!! jumps to 1: in func1, which is still in scope.  This could bite you after moving some blocks around but missing the f/b annotations.
    jcc 1f      # good: will jump forward to the next definition of 1:
    ...
1:
    ...
    ret

最好只写func1.afunc2.a

在某些目标(不包括x86-64和i386)上,有一些限制范围的本地标签可以让您避免意外跳转到错误的标签定义,但仍然无法使用有意义的标签名称:请参阅< strong>美元本地标签在手册的同一页面上(上面的链接)。

对于x86目标,

1$:是gas和clang的语法错误。

这很不幸,因为它是函数范围的,除非你在函数中使用任何带有有意义名称的标签(比如.Lmain_loop:)。