2014-02-10 1 views
12

assmbly의 스택을 통해 전달 인수를 연구하려고합니다. fedora 20, 64 비트 시스템을 사용하고 있습니다. 오류 : 'push'에 대한 명령어 접미사가 잘못되었습니다.

내가 다음 코드를 시도

,

pushl %의의 EBP

POPL의 %의 EBP 내가, 오류 오류를 얻을

: '푸시'

어떻게 되나요 잘못된 명령 접미사 나는이 오류를 극복했다! 내가하여 컴파일

, -ggstabs -o로 Function_Stack.o Function_Stack.c

답변

19

당신이 얻고있는 오류는 매우 단순한 사실에서 나온다 : 32 비트 모드에서 push 명령을 받아 16 bit와 32-bit immediates를 인수로 사용합니다. 그러나 64 비트 모드에서 사용되는 push 명령어는 16 비트 및 64 비트 즉시 처리 만 허용합니다. 코드를 64 비트로 명확하게 컴파일하므로 어셈블러에서 오류를 throw합니다. 이러한 명령을 인코딩 할 수 없기 때문입니다. 또한 push 명령에 접미사를 추가하여 피연산자 크기를 사용자가 직접 지정해야한다는 것을 명심하십시오. 방금 쓴 모든 내용은 pop에 대해 동일하지만 레지스터/메모리를 수용한다는 점을 제외하고는 즉시 처리하지 않습니다.

그러나 이어야하며 32 비트 및 64 비트 Linux 시스템 간의 ABI 차이점을 명심해야합니다. ABI는 매개 변수가 함수에 전달되는 방법과 사용자 모드 응용 프로그램에서 커널을 호출하는 방법을 지정합니다. 귀하의 코드는 32 비트 모드를 위해 명확하게 작성되었으며 인수를 전달하기 위해 스택을 사용하는 방법과 (매우) 사용되지 않는 int $0x80 시스템 호출 방법을 확인합니다. 64 비트 ABI에 대해 알아 보려면 this document을 참조하십시오.

또는 64 비트 시스템에서 32 비트 코드를 컴파일 할 수 있습니다. 이러한 실행 파일은 64 비트 시스템에 필요한 32 비트 런타임 라이브러리가 설치된 경우 작동합니다. 대부분의 배포판을 사용하면 여러 가지 방법으로 그렇게 할 수 있습니다. 귀하의 컴파일러 as, --32 스위치를 32 비트 코드를 방출했다.

+4

--32 스위치를 사용하여 성공적으로 obj를 생성했습니다. 이제 ld prog.0 -o prog, ld : i386 : i386 아키텍처의 입력 파일 'prog.o'의 아키텍처가 i386 : x86-64 출력과 호환되지 않습니다. ld의 국기는 무엇이되어야합니까? – InQusitive

+3

(참고 용) ld에는 "-melf_i386"-flag를 사용해보십시오. – Fabio

+1

잘 작동하지만 "바이너리 파일을 실행할 수 없습니다 : Exec 형식 오류"다음에 실행할 수 없습니까? = S –