【问题标题】:gcc inline asm embedding pointer to .rodata in .text, x86gcc inline asm 在 .text,x86 中嵌入指向 .rodata 的指针
【发布时间】:2011-01-28 10:47:04
【问题描述】:



我正在尝试使用内联汇编程序在代码部分中嵌入指向字符串的指针。但是 gcc 在符号名称的开头添加了一个 $,导致链接错误。

这是一个最小的示例,

static const char str[] = "bar";
int main()
{
    __asm__ __volatile__
    (
        "jmp    0f\n\t"
        ".long  %0\n\t"
        "0:"
        :
        : "i" ( str )
    );
    return 0;
}

构建

gcc -Wall -save-temps test.c -o test

给出错误

test.o: In function `main':
test.c:(.text+0x6): undefined reference to `$str'

查看 .s 临时文件,可以看到附加在 str 前面的 $

    .file   "test.c"
    .section    .rodata
    .type   str, @object
    .size   str, 4
str:
    .string "bar"
    .text
.globl main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
#APP
# 4 "test.c" 1
    jmp    0f
    .long  $str
    0:
# 0 "" 2
#NO_APP
    movl    $0, %eax
    leave
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
    .section    .note.GNU-stack,"",@progbits

认为我这样做是正确的,因为同样的方法适用于 ppc gcc,

<clip>
    b      0f
    .long  str
    0:
</clip>

再一次,也许它只是“运气”它适用于 ppc。问题是因为在使用 AT&T 语法时 $ 被用作立即数的前缀吗?

在这个简单的示例中,我可以通过在内联汇编器中硬编码符号名称“str”来解决此问题,但我确实需要将其作为内联汇编器的输入约束。

有没有人知道如何让它在 x86 目标上工作?

谢谢,
- 卢克

【问题讨论】:

    标签: gcc assembly x86 inline-assembly


    【解决方案1】:

    使用 clang 也会发生同样的事情,可能是因为代码生成器不知道 .long 中使用的操作数是 bing 而不是立即指令操作数。你的代码尝试类似:

    const char str[] = "bar";
    #define string(str)    __asm__ __volatile__ \
    ( \ 
        "jmp    0f\n\t" \
        ".long  " #str "\n\t" \
        "0:" \                          
    )
    int main()
    {       
    string(str);
    return 0;   
    }
    

    (我不得不删除 str 上的“静态”,因为编译器将其优化为未被引用。)

    【讨论】:

    • 这确实解决了我发布的示例,但不幸的是没有解决实际的用例。实际上是在使用 FILE 等,所以 gcc 正在生成像 .LC0 这样的临时符号,然后在寻找 $.LC0 时出现链接错误。希望避免在宏中生成符号名称,以避免可能的冲突(即使附加了 LINE)。认为我刚刚找到了一个解决方案......由于 AT&T 语法,正在添加 $,添加 -masm=intel 可以正常工作。感谢您查看此 Richard,非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2012-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 2013-04-08
    相关资源
    最近更新 更多