Перемещение метки после включения оптимизации в gcc - PullRequest
0 голосов
/ 25 мая 2011

У меня странная проблема после включения оптимизации уровня 1 в gcc.Затем я сохраняю метку и jmp обратно к ней из другой функции.

void
UMS__suspend_procr( VirtProcr *animatingPr )
{ 
   animatingPr->nextInstrPt = &&ResumePt;


   [Some Code and inline volatile asm]

   ResumePt:
   return;

}

Я делаю некоторые из этих переходов, и все они работают нормально.Проблема в том, что когда я включаю O1, он не сохраняет правильный адрес метки.Вместо этого он делает это:

804b14e:       8b 45 08                mov    0x8(%ebp),%eax
804b151:       c7 40 14 4e b1 04 08    movl   $0x804b14e,0x14(%eax)
804b158:       8b 55 08                mov    0x8(%ebp),%edx

Таким образом, программа возвращается назад еще до назначения.

1 Ответ

6 голосов
/ 25 мая 2011

Этот код недопустим для GNU C. Начнем с того, что вычисленные gotos (&&label) являются функцией, специфичной для GNU C, а не частью языка C, но это нормально, если вы используете GNU C. Однако, единственное место, где они действительны в GNU C, это оператор goto. Вы не можете использовать указатель со встроенным asm в качестве косвенного пункта назначения перехода / вызова, потому что настройка фрейма стека зависит от компилятора, и текущее логическое представление фрейма стека с точки inline asm и назначения метки может не совпадать , С явным оператором goto компилятор может исправить это, но с помощью asm он даже не может сказать, что это происходит.

Что касается общей картины, если вы пишете такой код, вам действительно следует переосмыслить некоторые свои предположения. Конечно, есть лучший способ выполнить то, что вы хотите.

...