2016-09-19 6 views
1

내 프로그램이 우분투에서 잘 작동합니다.오류 : SPARC에서 알 수없는 "%"기호

Solaris SPARC 시스템에서 gcc로 컴파일하면 오류가 발생합니다.

내가 같은 코드의 여러 조각이 있습니다

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와 인텔 문법의 문제가 될 수 있을까? – Olaf

답변

4

(원래 버전의 질문에는 SPARC Solaris 시스템의 오류라고 언급되지 않았으며 gcc의 이전 버전이 기본값으로 -std=c90에 설치되어있어 C90이라고했는데 오류 메시지가 나타납니다. C90에서 불법입니다.)


는 분, "하지 C90에 우분투에서 잘 작동하지만"를 기다립니다? /usr/ccs/bin/as (스크린 샷에 있음)은 Solaris와 유사합니다. 그 + 호스트 이름은 이것이 x86이 아닌 SPARC 머신이라는 단서입니다.


분명히 86 어셈블리는 유효 SPARC 어셈블리 구문 없습니다. 그것은 다른 CPU 아키텍처입니다.

당신이 gcc foo.c -S를 사용하고 결과 foo.s ASM 출력 파일 보았다했다면

, 당신은 당신의 asm 진술에 의해 그대로 삽입 된 텍스트를 제외하고, SPARC의 ASM의 모든 것을 볼 것입니다.

SPARC 구문은 레지스터 이름에 % 데코레이터를 사용하지만 레지스터 이름은 다릅니다. 예 : add %i0, %i1, %o0은 입력 레지스터 i0i1을 추가하여 결과를 출력 레지스터 o0에 저장합니다. (함수 결과에서와 같이 함수 인수 및 출력로서 입력. SPARC uses a sliding window onto a large virtual register file 또는 CPU 마이크로 아키텍처는 save 명령 실행 레지스터로부터인지에 따라, 메모리에 유출하지 않을 수.)

이러한 오류로부터 것을 기억 gcc가 아니라 Solaris 어셈블러. gcc를 사용하고 있지만 GNU 어셈블러 대신 시스템 어셈블러를 사용하고 있습니다.

어쨌든 #ifdef __x86__을 사용하여 해당 인라인 asm을 계속 사용하거나 SPARC 포트를 쓰는 대신 코드를 순수한 휴대용 C로 다시 작성하는 것이 좋습니다.


현재, 귀하의 asm 성명은 끔찍한 것 같습니다. 다른 버전의 gcc는 .LC0에 다른 상수를 저장하여 코드를 위반할 수 있습니다. 더 중요한 것은 입/출력 제약 조건을 사용하여 컴파일러에게 어떤 값이 어디에 있는지 알려주지 않는 것입니다. 함수 내에서 asm을 eax로 설정하는 것이 좋다고 가정한다면, 그것은 틀린 것입니다. 이 함수는 인라인 될 수 있으며, asm은 함수가 인라인 된 곳 어디에서나 자유롭게 떠 다니고 있습니다. GNU C 인라인 asm 튜토리얼에 대한 링크는 the end of this answer을 참조하십시오.

또한 인라인 변환을 위해 인라인 asm이 필요하지 않습니다.uint32_t le32toh(uint32_t little_endian_32bits);과 같이 endian.h functions을 사용하면 더 나은 asm을 얻을 수 있습니다. gcc builtins 또는 inline asm을 사용하면 컴파일러에서 최적의 어셈블리 출력을 얻을 수 있습니다.

도 참조하십시오. 에 올바르게 적용된 경우에도 적용됩니다.

+0

사진과 죄송합니다. 죄송합니다. SunOS sparc입니다. 나는 그것이 오류이기 때문에 C90이라고 생각했다. ISO C90은이 오류가 오기 전에 혼합 된 선언과 코드를 금지하고있다. – Patrick

+0

@ 패트릭 : gcc의 구버전은'-std' 옵션을 사용하지 않으면 C90 컴파일러가됩니다. gcc가 무엇인가가 왜 에러인지를 알려주는 것과 관련이 있습니다. C99에서 오류가 아닌 경우 (예 : for (int i = 0; ...)은 C99 이상에서만 유효합니다. –

+0

@ 패트릭 : 텍스트 버전을 추가 한 후 내 downvote를 삭제했습니다. 아직 답변을 알기 위해 필요한 모든 정보가 포함되어 있지 않기 때문에 여전히 좋은 질문이 아닙니다. 이 질문에서 SPARC 또는 Solaris에 대한 언급이 없었기 때문에 Dalhousie의 컴퓨터 과학 부서에서 학부모가되었을 때 Solaris SPARC 시스템을 사용하고 난 후에 우리는 하나의 작은 베오 울프 클러스터를위한 시스템 관리자로 일할 수있었습니다. 우리가 Solaris의 기본 설치를 유지했던 Sun에서 구입했습니다. 나는 총 혼란에 대한 논평에서 다른 사람들의 반응에 전혀 놀란 적이 없다. –