2016-09-19 21 views
1

Моя программа отлично работает на Ubuntu.ошибка: неизвестный символ "%" на SPARC

Обнаружена ошибка при компиляции с помощью gcc в системе Solaris SPARC.

У меня есть несколько кусков кода, как:

printf("endian_convert: %s\n", endian_convert); 

asm("movl $8, %esi\n\t" 
       "movl $.LC0, %edi\n\t" 
       "movl $0, %eax"); 

Это ошибка я получаю на SPARC:

gcc -g -Wall -Werror -pedantic -Wextra src/utfconverter.c -o bin/utf 

/usr/ccs/bin/as: "/var/tmp//cc9czJEf.s", line 957: error: unknown "%"-symbol 
/usr/ccs/bin/as: "/var/tmp//cc9czJEf.s", line 957: error: statement syntax 
....... 
/usr/ccs/bin/as: "/var/tmp//cc9czJEf.s", line 1058: error: unknown "%"-symbol 
/usr/ccs/bin/as: "/var/tmp//cc9czJEf.s", line 1058: error: statement syntax 
*** Error code 1 make: Fatal error: Command failed for target `utf' 

Таким образом, символ "%" рассматривается как неизвестный на SPARC?

Как исправить это и заставить его работать на SPARC?

+3

Не размещайте изображения текста! И это не C90, а ассемблер. Проверьте временный файл! – Olaf

+1

Попробуйте ускользнуть: '%% esi'. –

+0

@KerrekSB: Разве это не добавит два символа '%'? Я не знаком с сборкой x86, но может ли это быть проблемой с AT & T против синтаксиса Intel? – Olaf

ответ

4

(В исходной версии вопроса не упоминалось, что ошибки были из системы SPARC Solaris и назывались только C90, потому что старая версия gcc, установленная на нем, по умолчанию была -std=c90, что приводило к сообщениям об ошибках о вещах, которые являются незаконными в C90.)


подождите, "отлично работает на Ubuntu, но не на C90"? /usr/ccs/bin/as (на скриншоте) выглядит как Solaris. Это + имя хоста является ключом к тому, что это может быть машина SPARC, а не x86 вообще.


Очевидно x86 сборка не действует СПАРК сборка синтаксиса. Это другая архитектура процессора.

Если бы вы использовали gcc foo.c -S и посмотрели на файл вывод foo.s ASM, вы бы увидели, что он был полон СПАРК ассемблера, для текста, вставленного буквально ваших asm заявления, за исключением.

Синтаксис SPARC использует% декораторов для имен регистров, но имена регистров различаются. например add %i0, %i1, %o0 добавляет регистры ввода i0 и i1, сохраняя результат в выходном регистре o0. (Вход, как в функции арга и выходе, как в результате функции. SPARC uses a sliding window onto a large virtual register file, что может или не может проливать памяти, в зависимости от того, микроархитектуры процессора из регистров при выполнении save инструкции.)

Помните, что эти ошибки из ассемблер Solaris, а не gcc. Вы используете gcc, но вместо ассемблера GNU используется системный ассемблер.

В любом случае, я рекомендую переписать код в чистый переносимый C, а не использовать #ifdef __x86__, чтобы продолжать использовать этот встроенный asm или написать порт SPARC.


BTW, ваше заявление asm выглядит ужасно. Другая версия gcc может хранить другую константу в .LC0, нарушая ваш код. Что еще более важно, вы не используете ограничения ввода/вывода, чтобы сообщить компилятору, какое значение есть где. Если вы предполагаете, что нормально использовать eax в asm внутри функции, это неверно. Функция может и будет встроена, а затем ваш asm просто плавает свободно посередине, где бы ваша функция не была встроена. См. the end of this answer для ссылок на некоторые учебные материалы GNU C inline asm.

Кроме того, вам не нужен встроенный asm для преобразования endian.Вы получите лучше asm от использования endian.h functions, например uint32_t le32toh(uint32_t little_endian_32bits);, которые используют встроенные функции gcc или inline asm, чтобы заставить компилятор сделать оптимальный выход сборки.

См. Также https://gcc.gnu.org/wiki/DontUseInlineAsm, который применяется, даже если вы сделали умеет использовать его должным образом.

+0

Извините за фотографии и да, это SunOS sparc. Я думал, что это C90, потому что я получил ошибку: ISO C90 запрещает смешанные декларации и код для моей программы c до этой ошибки. – Patrick

+0

@Patrick: Ну, старые версии gcc по умолчанию являются компилятором C90, если вы не используете какие-либо опции '-std'. Для gcc важно указать, почему что-то является ошибкой, особенно. когда это не ошибка на C99. (например, 'for (int i = 0; ...)' действует только на C99 и позже). –

+0

@Patrick: Я удалил свой нисходящий поток, так как вы добавили текстовую версию. Это все еще не очень хороший вопрос, так как он не содержит всю информацию, необходимую для уверенного ответа. Ничто в этом вопросе не упоминает SPARC или Solaris, так что вам просто повезло, что в отделе компьютерных наук в Dalhousie использовались системы Solaris SPARC, когда я был младшим, и позже я работал в качестве системного администратора для нескольких небольших кластеров beowulf, в том числе один из нас купленный у Sun, где мы сохранили стандартную установку Solaris. Я вовсе не удивлен реакцией всех в комментариях полной путаницы. –