2016-09-19 2 views
1

Mon programme fonctionne correctement sur Ubuntu.erreur: symbole "%" inconnu sur SPARC

Il rencontre une erreur lorsque je le compile avec gcc sur un système Solaris SPARC.

J'ai plusieurs morceaux de code comme:

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

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

Ceci est l'erreur que je reçois sur 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' 

Ainsi, le symbole "%" est considérée comme inconnue sur SPARC?

Comment puis-je résoudre ce problème et le faire fonctionner sur SPARC?

+3

Ne postez pas d'images de texte! Et ce n'est pas un C90, mais un assembleur. Vérifiez le fichier temporaire! – Olaf

+1

Essayez d'échapper: '%% esi'. –

+0

@KerrekSB: N'ajouterait pas deux symboles '%'? Je ne suis pas familier avec l'assemblage x86, mais pourrait-il être un problème avec la syntaxe AT & T vs Intel? – Olaf

Répondre

4

(La version originale de la question ne mentionnait pas que les erreurs provenaient d'un système SPARC Solaris, et l'appelait simplement C90 car l'ancienne version de gcc installée par défaut était -std=c90, ce qui entraînait des messages d'erreur sont illégaux en C90.)


Attendez une minute, "fonctionne bien sur Ubuntu mais pas sur C90"? /usr/ccs/bin/as (dans votre capture d'écran) ressemble à Solaris. Cela + le nom d'hôte est un indice que cela pourrait être une machine SPARC, pas du tout x86.


assemblage x86 est évident que la syntaxe ne assembleur SPARC valide. C'est une architecture de CPU différente.

Si vous avez utilisé gcc foo.c -S et regardé le fichier de sortie foo.s asm résultant, vous verriez qu'il était plein de SPARC asm, à l'exception du texte inséré littéralement par vos asm déclarations.

La syntaxe SPARC utilise% decorators sur les noms de registre, mais les noms de registre sont différents. par exemple. add %i0, %i1, %o0 ajoute les registres d'entrée i0 et i1, en stockant le résultat dans le registre de sortie o0. (Entrée comme fonction arg et de sortie comme résultat de la fonction. SPARC uses a sliding window onto a large virtual register file qui pourrait ou ne pourrait pas renverser la mémoire, selon que la microarchitecture CPU est hors des registres lors de l'exécution. Instruction save)

Rappelez-vous que ces erreurs sont de l'assembleur Solaris, pas de gcc. Vous utilisez gcc mais il utilise l'assembleur du système à la place de l'assembleur GNU.

Quoi qu'il en soit, je recommande de réécrire votre code dans C pur portable, plutôt que d'utiliser #ifdef __x86__ pour continuer à utiliser asm inline, ou en écrivant un port SPARC de celui-ci.


BTW, votre déclaration ASM semble horrible. Une version différente de gcc pourrait stocker une constante différente au .LC0, brisant votre code. Plus important encore, vous n'utilisez pas de contraintes d'entrée/sortie pour dire au compilateur quelle valeur est où. Si vous supposez que vous pouvez définir eax dans asm à l'intérieur d'une fonction, c'est incorrect. La fonction peut et va s'introduire, et votre asm est en train de flotter librement au milieu de votre fonction. Voir the end of this answer pour des liens vers des tutoriels GNU C inline asm.

De même, vous n'avez pas besoin d'asline inline pour convertir en endian.Vous obtiendrez mieux asm d'utiliser endian.h functions comme uint32_t le32toh(uint32_t little_endian_32bits); qui utilisent gcc builtins ou inline asm pour que le compilateur fasse lui-même une sortie d'assemblage optimale.

Voir aussi https://gcc.gnu.org/wiki/DontUseInlineAsm, ce qui s'applique même si vous avez fait comment l'utiliser correctement.

+0

Désolé pour les photos et oui, c'est SunOS sparc. Je pensais que c'était C90 parce que j'ai eu une erreur: ISO C90 interdit les déclarations mixtes et le code pour mon programme c avant cette erreur. – Patrick

+0

@Patrick: Eh bien, les anciennes versions de gcc sont par défaut un compilateur C90 si vous n'utilisez aucune option '-std'. Il est pertinent pour gcc de vous dire pourquoi quelque chose est une erreur, esp. quand ce n'est pas une erreur dans C99. (par exemple 'for (int i = 0; ...)' n'est valide que dans C99 et plus tard). –

+0

@Patrick: J'ai supprimé mon downvote depuis que vous avez ajouté une version texte. Ce n'est toujours pas une bonne question, car elle ne contient pas toutes les informations nécessaires pour connaître la réponse à coup sûr. Rien dans la question ne mentionne SPARC ou Solaris, alors vous avez de la chance que le département informatique de Dalhousie ait utilisé les systèmes Solaris SPARC quand j'étais étudiant de premier cycle, et j'ai ensuite travaillé comme administrateur système pour quelques petites grappes beowulf, dont une acheté à Sun où nous avons conservé l'installation par défaut de Solaris. Je ne suis pas du tout surpris par la réaction de tout le monde dans les commentaires de confusion totale. –