Если происходит сбой с "неопределенной ссылкой на `saved_sp'" (что на самом деле является ошибкой компоновщика, а не ошибкой компилятора), когда saved_sp
равно static
, но работает, когда это не так, то вполне вероятно, что компилятор решил, что saved_sp
не используется в вашем исходном файле, и поэтому решил полностью исключить его из скомпилированного кода, который передается ассемблеру.
Компилятор не понимает ассемблерный код внутри блока asm
; он просто вставляет его в генерируемый им ассемблерный код. Таким образом, он не знает, что блок asm
ссылается на блок saved_sp
, и если больше ничего в коде C никогда не читает из него, он волен решить, что он полностью не используется, особенно если у вас включены какие-либо параметры оптимизации.
Вы можете сообщить gcc
, что saved_sp
используется чем-то, чего он не может видеть, и, таким образом, запретить ему выбрасывать его, добавив атрибут used
(см. документация атрибутов переменных, примерно в середине страницы), например:
static long __attribute__((used)) saved_sp;
Вот полностью рабочий пример:
$ cat test.c
#ifdef FIXED
static long __attribute__((used)) saved_sp;
#else
static long saved_sp;
#endif
int main(void)
{
__asm__ __volatile__ (
"movq saved_sp, %rsp\n\t" );
}
$ gcc -m64 -o test test.c
$ gcc -m64 -O1 -o test test.c
/tmp/ccATLdiQ.o: In function `main':
test.c:(.text+0x4): undefined reference to `saved_sp'
collect2: ld returned 1 exit status
$ gcc -m64 -DFIXED -O1 -o test test.c
$
(Это из 32-битной системы сжатия Debian с gcc 4.4.5, которая мне больше всего подходит; -m64
вполне может быть ненужным в вашей системе.)
person
Matthew Slattery
schedule
10.01.2012
gcc
версию. На моем компьютере с Ubuntugcc 4.4.4
доволен вашим кодом как есть. - person NPE   schedule 11.01.2012movq _saved_sp, %rsp
, обратите внимание на дополнительное подчеркивание? - person Alexey Frunze   schedule 11.01.2012-S
, и посмотреть, как компилятор называет переменную? - person Alexey Frunze   schedule 11.01.2012