gcc内联asm在.text,x86中嵌入指向.rodata的指针

时间:2011-01-28 10:47:05

标签: gcc assembly x86 inline-assembly



我正在尝试使用内联汇编程序在代码部分中嵌入指向字符串的指针。但是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临时文件,可以看到额外的$ preped到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&amp; T synax时$被用作immediates的前缀吗?

在这个简单的例子中,我可以通过在内联汇编程序中对符号名称“str”进行硬编码来解决这个问题,但实际上需要它作为内联汇编程序的输入约束。

有没有人对如何在x86目标上运行有任何想法?

谢谢,
- 卢克

1 个答案:

答案 0 :(得分:0)

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

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上的“static”,因为编译器将其优化为未被引用。)