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

Bul*_* M. 2 syntax assembly x86-64 gnu-assembler

要在多个函数中定义相同的本地标签:

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

main:
    push %rbp
    mov %rsp, %rbp
.a:
    leave
    ret
Run Code Online (Sandbox Code Playgroud)

奇怪地得到错误:

$ clang -c main.s
main.s:13:1: error: invalid symbol redefinition
.a:
^
Run Code Online (Sandbox Code Playgroud)

当我使用yasm时,它允许多个功能使用相同的本地标签。你有什么线索吗?

Pet*_*des 5

与NASM不同,gas语法.label不是功能(实际上.在非标签之前)的局部功能。

.Llabel是“本地”符号名称,表示它不在符号表中。它在整个文件中仍然可见,因此GNU as手册未将其称为本地标签。


还有在气体语法局部标签,但他们不是函数作用域。(请参阅上面的链接)。您必须使用前进/后退注释来引用它们,否则它们是数字常量而不是标签。(例如,mov $1, %eax将文字1放入eax中,而不是最新的地址中1:)。

更重要的是,您不能给他们提供有意义的名称,例如.Lcopy_loop.Linput_non_zero。它们在宏定义中或在可能内联到多个地方或由优化程序以其他方式复制的内联汇编中很有用。否则,应该使用有意义的名称

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
Run Code Online (Sandbox Code Playgroud)

最好只写func1.afunc2.a


在某些目标上(不包括x86-64和i386),有有限范围的本地标签,可以避免意外跳转到标签的错误定义,但仍不能使用有意义的标签名称:请参见上的Dollar Local Labels。手册的同一页(上面的链接)。

1$: 是x86目标在gas和clang中的语法错误。

不幸的是,除非您在函数内使用任何带有有意义名称的标签(例如.Lmain_loop:),否则它将是功能范围的。