2016-09-20 7 views
1

Хотите определить ту же локальную метку в нескольких функциях:Почему не удается определить такую ​​же локальную метку в нескольких функциях?

.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 это позволило одинаковые локальные метки в нескольких функций. У вас есть ключи?

+0

Вы пытались скомпилировать с 'as' вместо clang для тестирования? –

+0

В некоторых ассемблерах вы префикс «@» (или «@@») перед ярлыками, чтобы сделать их локальными, поэтому вы можете использовать один и тот же ярлык многократно («@@ mylabel»). –

+1

Попробуйте использовать '1:', '2:' и т. Д., Как это сделано с GNU as. Посмотрите [здесь] (https://sourceware.org/binutils/docs-2.19/as/Symbol-Names.html) для получения дополнительной информации. – Downvoter

ответ

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.a или func2.a.


На некоторых целях (не включая x86-64 и i386), то ограничивается-Scope локальных меток, которые позволяют избежать случайного прыгая на неправильное определение метки, но вы все еще не можете использовать содержательную метку имена: См. Доллар Местные ярлыки на той же странице руководства (ссылка выше).

1$: является синтаксической ошибкой в ​​газе и clang для целей x86.

Это несчастливо, потому что это будет функциональный, если вы не используете в своих функциях какие-либо ярлыки со значимыми именами (например, .Lmain_loop:).

+0

Я также прочитал руководство. У вас есть какие-либо советы/хорошие привычки использовать ярлыки вместо использования числовых меток? –

+1

@BulatM: это в основном тот же принцип, что и имена переменных или имена имен вспомогательной функции 'static inline' в C. Обычно имя должно описывать, почему вы идете туда (' .Linput_was_zero') или то, что делает блок ('.Learly_out') или что-то в этом роде. –

 Смежные вопросы

  • Нет связанных вопросов^_^