У меня есть сценарий в GCC, вызывающий у меня проблемы. Я получаю не то поведение, которого я ожидаю. Подводя итог ситуации, я предлагаю несколько новых инструкций для x86-64, которые реализованы в симуляторе оборудования. Чтобы протестировать эти инструкции, я беру существующий исходный код C и вручную кодирую новые инструкции с использованием шестнадцатеричного числа. Поскольку эти инструкции взаимодействуют с существующими регистрами x86-64, я использую списки ввода / вывода / закрытия для объявления зависимостей для GCC.
Что происходит, так это то, что если я вызываю функцию, например printf зависимые регистры не сохраняются и не восстанавливаются.
Например
register unsigned long r9 asm ("r9") = 101;
printf("foo %s\n", "bar");
asm volatile (".byte 0x00, 0x00, 0x00, 0x00" : /* no output */ : "q" (r9) );
101 был назначен на r9, а встроенная сборка (в данном примере - подделка) зависит от r9. Это работает правильно при отсутствии printf, но когда он есть, GCC не сохраняет и не восстанавливает r9, и к моменту вызова моей пользовательской инструкции существует другое значение.
Я подумал, что, возможно, GCC мог тайно изменить присвоение переменной r9, но когда я это сделаю
asm volatile (".byte %0" : /* no output */ : "q" (r9) );
и посмотрите на вывод сборки, он действительно использует% r9.
Я использую gcc 4.4.5. Как вы думаете, что может происходить? Я думал, что GCC всегда будет сохранять и восстанавливать регистры при вызове функций. Есть ли способ добиться его соблюдения?
Спасибо!
РЕДАКТИРОВАТЬ: Кстати, я компилирую программу вот так
gcc -static -m64 -mmmx -msse -msse2 -O0 test.c -o test