2012-01-10 4 views
3

Я пытаюсь использовать локальную переменную потока в встроенной сборке, но когда я вижу дизассемблированный код, кажется, что компилятор не генерирует правильный код. Для следующего встроенного кода, где saved_sp является глобально объявлен __thread long saved_sp,Локальные переменные нитей и встроенная сборка

__asm__ __volatile__ (
     "movq %rsp, saved_sp\n\t"); 

Разборка выглядит следующим образом.

mov %rsp,0x612008 

Что явно не правильно, потому что я знаю, что GCC использует фсов сегмента для резьбы локальных переменных. Он должен был сгенерировать что-то вроде

mov %rsp, fs:somevalue 

, которого нет. Почему это так? Является ли использование локальных переменных потока в встроенной сборке проблематичным?

+0

Я не думаю, что GCC так или иначе изменяет код встроенного ассемблера. Скорее всего, вам нужно явно указать префикс переопределения сегмента. Попробуйте вставить '' .byte 0x64 \ n \ t "' перед '" movq% rsp, saved_sp \ n \ t "'. –

ответ

4

Простая вещь, которая, несомненно, будет работать, - это сделать указатель на локальную переменную потока и записать на нее.
Ваш компилятор обязательно сделает long *saved_fp_p = &saved_fp правильно, а встроенная сборка будет работать только с saved_fp_p, которая является локальной переменной.

Вы также можете использовать входной и выходной синтаксис ССЗА:

__asm__ __volatile__ (
    "mov %%rsp, 0(%0)" : : "r" (&saved_sp) 
); 

Это ставит компилятор, отвечающие за разрешение адреса saved_fp, и код сборки получает его в регистре.

Мы обнаружили, что это работает,

__asm__ __volatile__ asm ("mov %rsp,%0" : "=m" (saved_sp)) 
+0

Это хорошее умное решение, но я бы предпочел написать непосредственно в saved_sp, вместо того, чтобы использовать регистр, чтобы указать его. – MetallicPriest

+1

возможно 'asm (" mov% rsp,% 0 "::" m "(saved_fp))' будет работать. Важная роль заключается в том, чтобы компилятор, а не ассемблер, обрабатывал переменную saved_fp. Компилятор, безусловно, сделает это правильно, ассемблер, похоже, делает это плохо. – ugoren

+0

Это действительно работает! Благодаря! – MetallicPriest

Смежные вопросы