gcc встроенный asm-встраивание указателя на .rodata в .text, x86 - PullRequest
1 голос
/ 28 января 2011



Я пытаюсь встроить указатель на строку в разделе кода с помощью встроенного ассемблера. Но 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>

Опять же, может быть, это просто "удача", это работает для КПК. Проблема в том, что $ используется в качестве префикса для непосредственных при использовании Synax AT & T?

В этом простом примере я могу обойти эту проблему, жестко закодировав имя символа "str" ​​во встроенном ассемблере, но на самом деле нужно, чтобы это было ограничение ввода для встроенного ассемблера.

У кого-нибудь есть идеи, как заставить это работать над целями x86?

Спасибо
- Люк

1 Ответ

0 голосов
/ 28 января 2011

То же самое происходит с использованием 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, потому что компилятор оптимизировал его как не ссылаться.)

...