2014-12-08 4 views
0

내가 64 비트 리눅스에서 실행되는 GNU C 코드에 대한 몇 가지 확장 조립 최적화를하고있는 중이 야에 - 64 호출 규칙에 따라 지역 스택을 설정. 어셈블리 코드에서 디버깅 메시지를 인쇄하고 싶었습니다. 나는이 상황에서 누군가가 내가해야 할 일을 설명 할 수 있기를 바라고있다. 함수의 네 agruments이 클래스 INTEGER의 때문에리눅스

void test(int a, int b, int c, int d){ 


     __asm__ volatile (

     "movq $0, %%rax\n\t" 
     "pushq %%rax\n\t" 
     "popq %%rax\n\t" 


     : 
     :"m" (a) 
     :"cc", "%rax" 
     ); 

} 

, 그들은 레지스터를 통과 한 후 스택으로 푸시됩니다

이 샘플 기능을 살펴보십시오. 나에게 이상한 것은 gcc가 실제로 그것을 수행하는 방법입니다

test: 
     pushq %rbp 
     movq %rsp, %rbp 
     movl %edi, -4(%rbp) 
     movl %esi, -8(%rbp) 
     movl %edx, -12(%rbp) 
     movl %ecx, -16(%rbp) 

     movq $0, %rax 
     pushq %rax 
     popq %rax 

     popq %rbp 
     ret 

전달 된 인수는 스택으로 푸시되지만, 스택 포인터는 감소되지 않습니다. 내가 pushq %rax을 수행 할 때 따라서, ab의 값을 덮어 씁니다. 궁금한 점은 gcc가 로컬 스택을 올바르게 설정하도록 요청하는 방법이 있습니까? 함수 호출에서 pushpop을 사용하지 않아도됩니까?

답변

2

- 64 ABI 스택 포인터 아래에 128 바이트의 적색 영역을 제공하고, 컴파일러는 그것을 사용하기로 결정했다. -mno-red-zone 옵션을 사용하여 사용 중지 할 수 있습니다.

+0

감사합니다. 함수 대 함수를 기반으로이 옵션을 적용 할 수있는 방법이 있습니까? – Ivan

+0

그렇게 생각하지 마십시오. 그러나 당신은 당신의 기능을 별도의 파일에 넣을 수 있습니다. 또한 코드가이 설정에 의존하는 경우 잘못된 작업을 수행하고있는 것입니다. – Jester