2016-09-20 5 views
1

여러 기능에 같은 지역 레이블을 정의 할 수 : 원함 여러 기능에 동일한 로컬 레이블을 허용여러 기능에서 동일한 로컬 레이블을 정의 할 수없는 이유는 무엇입니까?

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

것은 내가 사용했다 yasm :

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

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

가 이상하게 오류가 발생합니다. 실마리가 있습니까?

+0

테스트를 위해 clang 대신'as'를 사용하여 컴파일을 시도 했습니까? –

+0

일부 어셈블러에서는 레이블 앞에 @를 붙이기 때문에 (@@ mylabel) 동일한 레이블을 여러 번 사용할 수 있습니다. –

+1

GNU as와 같이'1 :','2 :'등을 사용해보십시오. 자세한 내용은 [여기] (https://sourceware.org/binutils/docs-2.19/as/Symbol-Names.html)를 참조하십시오. – Downvoter

답변

4

NASM과 달리 .label은 가스 구문에서 (실제로는 . 레이블 앞에 선행하는) 기능에 국한되지 않습니다.

.Llabel은 "로컬"심볼 이름으로 기호 테이블에는 포함되지 않습니다. 파일 전체에서 계속 볼 수 있으므로 the GNU as manual은 로컬 라벨이라고 부르지 않습니다. 이


가스 구문 지역 라벨,하지만 그들은 범위 기능이 아닙니다. (위의 링크 참조). 너 을 사용하여 참조를 위해 앞뒤 주석을 사용합니다. 그렇지 않으면 레이블 대신 숫자 상수입니다. (예 : mov $1, %eax은 가장 최근의 주소가 아닌 eax에 리터럴 1을 넣습니다. 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을 포함하지 않음) 일부 대상에


, 당신은 라벨의 잘못된 정의에 점프 실수하지 않도록하자 지역 라벨이 범위 제한되어 있지만, 당신은 여전히 ​​의미있는 라벨을 사용할 수 없습니다 이름 : 달러 로컬 라벨 참조 페이지 (위 링크)를 참조하십시오.

는 x86 타겟에서 gas와 clang의 구문 오류입니다.

함수 내에 의미있는 이름을 가진 레이블 (예 : .Lmain_loop:)을 사용하지 않으면 기능 범위가 적용될 수 있으므로 불행합니다.

+0

나는 설명서를 너무 읽었습니다. 숫자 레이블을 사용하는 대신 레이블 사용에 대한 팁이나 좋은 습관이 있습니까? –

+1

@BulatM : C에서 변수 이름이나'정적 인라인'도우미 함수 이름을 만드는 것과 기본적으로 같은 원리입니다. 보통 이름은 왜 거기에 가야하는지 ('.Linput_was_zero') 또는 블록이 무엇인지를 기술해야합니다 ('.Learly_out'), 또는 그런 것. –