gpt4 book ai didi

C 内联汇编标签问题

转载 作者:太空宇宙 更新时间:2023-11-03 23:33:25 26 4
gpt4 key购买 nike

我目前是汇编的初学者,正在学习如何在类里面使用 C 语言的内联汇编。话虽这么说,但我在编译文件时遇到了这个特殊错误:

/tmp/cckHnU89.s: Assembler messages:/tmp/cckHnU89.s:550: Error: symbol `.L16' is already defined/tmp/cckHnU89.s:571: Error: symbol `.L18' is already defined/tmp/cckHnU89.s:576: Error: symbol `.L17' is already defined

我尝试用其他名称替换标签的名称,因为我从 .s 文件中注意到标签 .L16、.L17 和 .L18 在我的主要方法以及我的一个函数中使用。但是,什么时候我刚刚结束了运行程序的段错误。有没有办法更改标签的名称或其他东西来修复这显然是命名冲突?

就我的 CPU 而言,我运行的是 Intel Pentium T4500 处理器,并且我正在使用 gcc 4.4.3 版进行编译。对于内联汇编部分,我的代码有 300 多行,所以我会放过任何阅读此代码的人。本质上,我只是在寻找一个关于通常如何解决产生上述错误的命名冲突的一般答案。任何见解将不胜感激。

最佳答案

我的直觉是(我刚刚用 g++ -Sgcc -S 验证过)您自己的标签完全模仿 GCC 中自动分配给汇编程序代码的标签的命名方案 ( .L<num> )。

执行以下操作:

# for C:
gcc -S source.c
# for C++
g++ -S source.cpp

... 然后 cat (或 less )结果 .s文件(相同的基本名称,.s 后缀,例如 source.s )。您会发现该方案的许多标签 ( .L<num> )。现在,如果您自己创建包含与已经自动创建的标签(从您的 C 代码)相同名称的内联程序集,那显然会导致冲突。

所以要点:不要使用 .L<num>作为标签的命名方案,因为它会发生冲突。

一般名称以.L开头好像是来找麻烦的。


示例 ( test.cpp ),用 g++ -S test.cpp 编译:

#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;
}

在 x64 上编译(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 开头的名称在生成的汇编文件中。

关于C 内联汇编标签问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10080939/

26 4 0