Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
gcc内联asm在.text中嵌入指向.rodata的指针,x86_Gcc_Assembly_X86_Inline Assembly - Fatal编程技术网

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

gcc内联asm在.text中嵌入指向.rodata的指针,x86,gcc,assembly,x86,inline-assembly,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 ) ); re



我正在尝试使用内联汇编程序在代码段中嵌入一个指向字符串的指针。但是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 temp文件,可以看到额外的$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>

b0f
.朗街
0:
再说一次,也许这只是“运气”,它对ppc有效。问题是否是因为在使用AT&T synax时,$被用作即时消息的前缀

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

有人对如何在x86目标上实现这一点有什么想法吗

谢谢,

-Luke

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

这确实修复了我发布的示例,但不幸的是没有修复实际用例。实际上正在使用文件等,所以gcc生成了.LC0之类的临时符号,然后在查找$.LC0时出现了链接错误。要避免在宏中生成符号名称,以避免可能的冲突(即使出现了行)。我想我刚刚找到了一个解决办法。。。由于AT&T语法,添加了$masm=intel,因此可以正确工作。谢谢你看这个Richard,非常感谢。