私の勘では、独自のラベルを正確に自動的にGCCにアセンブラコードに割り当てられたラベルの名前付けスキーム(.L<num>
)を模倣していること(と私はちょうどg++ -S
とgcc -S
でそれを検証する)です。
は、次の操作を行います(たとえば、同じベース名、.s
サフィックス、source.s
)
# for C:
gcc -S source.c
# for C++
g++ -S source.cpp
...そしてcat
(またはless
)結果.s
ファイルを。あなたはそのスキームの多くのラベル(.L<num>
)を見つけるでしょう。今では、自動的に作成されたラベル(Cコードから)と同じ名前を持つインラインアセンブリを自分で作成すると、明らかに衝突につながります。
したがって、gist:ラベルの命名規則として.L<num>
を使用しないでください。これは衝突するためです。
から始まる名前は、.L
で始まります。
例(test.cpp
)、g++ -S test.cpp
でコンパイル:x64でコンパイル
#include <cstdio>
int main(int argc, char**argv)
{
switch(argc)
{
case 0:
printf("test 0\n");
break;
case 1:
printf("test %d\n", argc);
break;
case 2:
printf("test %d -> %s\n", argc, argv[0]);
break;
default:
printf("Default\n");
break;
}
return 0;
}
(test.s
の内容):
.file "test.cpp"
.section .rodata
.LC0:
.string "test 0"
.LC1:
.string "test %d\n"
.LC2:
.string "test %d -> %s\n"
.LC3:
.string "Default"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
subq $16, %rsp
movl %edi, -4(%rbp)
movq %rsi, -16(%rbp)
movl -4(%rbp), %eax
cmpl $1, %eax
je .L4
cmpl $2, %eax
je .L5
testl %eax, %eax
jne .L8
.L3:
movl $.LC0, %edi
call puts
jmp .L6
.L4:
movl -4(%rbp), %eax
movl %eax, %esi
movl $.LC1, %edi
movl $0, %eax
call printf
jmp .L6
.L5:
movq -16(%rbp), %rax
movq (%rax), %rdx
movl -4(%rbp), %eax
movl %eax, %esi
movl $.LC2, %edi
movl $0, %eax
call printf
jmp .L6
.L8:
movl $.LC3, %edi
call puts
.L6:
movl $0, %eax
leave
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Debian 4.4.5-8) 4.4.5"
.section .note.GNU-stack,"",@progbits
を得アセンブラファイルに.L
で始まる名前を守っ。
関連するコードを表示できますか?私たちに何もない場合は、伝えるのは難しいです。 – Mysticial
コードだけでなく、コンパイルするCPUと使用しているCコンパイラについて教えてください。 – user9876
これは、(1)必要な情報を提供するための正直な試み、(2)問題に対処するために既に試行されたことを説明すること、(3)特定の質問をすること、 –