2013-06-17 2 views
1

많은 경우에 C 함수 (예 : 정렬 알고리즘 셸 정렬)를 컴파일 할 때 stackaddress (i는 호출되는 것으로 보입니까?) ebp-4/-4 (% ebp)/[ebp] -4 또는 무엇이든간에, 알다시피, 보통 첫 번째 지역 변수에 사용되며, 내 경우에는 사용되지 않습니다.인텔 x86 - 왜 -4 (% ebp)가 아무 것도 말하지 않습니까?

그래서 어떤 로컬 변수에 사용되지 않았기 때문에 어떤 용도로 사용되는지 알고 있는지 궁금 해서요.

또한, 로케일 변수에 스택 공간을 할당하기 위해 스택 포인터에서 20을 뺀다 - 그러나 값은 여전히 ​​-24 (% ebp)로 저장된다. -20까지만 방이 만들어 졌을 때 어떻게 가능할까? ??

는 C-기능은 다음과 같이 lookes :

void shellsort(int a[], unsigned int n) { 
    unsigned int gap, i, j; 
for (gap = n/2; gap > 0; gap = gap == 2 ? 1 : 5 * gap/11) { 
     for (i = gap; i < n; i++) { 
      int tmp = a[i]; 
      for (j = i; j >= gap && tmp < a[j - gap]; j -= gap) 
       a[j] = a[j - gap]; 
      a[j] = tmp; 
     } 
    } 
} 

을 그리고 이것은 86에 gcc -S 32 비트 우분투 사전에

12(%ebp) = n 
8(%ebp) = a[] 
-8(%ebp) = tmp 
-12(%ebp) = j 
-16(%ebp) = i 
-20(%ebp) = gap 
-24(%ebp) = (gap * 4) + gap 

감사합니다 :)

+2

이렇게하는 코드를 보여줄 수 있습니까? – harold

+1

질문을 편집하고 {} 서식 지정 버튼을 사용하십시오. –

+1

어떤 플랫폼?어떤 컴파일러와 컴파일러 플래그? 생성 된 어셈블리는 무엇입니까? –

답변

1

질문에 두 부분이 있습니다.

제가 이해하는 첫 번째 것은 [EBP-4]가 사용되는 것과 관련이 있습니다. 이를 위해서는 x86 스택 프레임에 대한 요약을 What is stack frame in assembly?으로 읽어보십시오.

질문의 전체 20/24 부분에 올바르게 대답하려면 해체 된 코드를 살펴 봐야합니다. 다음은 사용자가 제공 한 C 코드의 디스 어셈블리에서 추출한 것입니다.

.LFB0: 
     .cfi_startproc 
     pushl %ebp 
     .cfi_def_cfa_offset 8 
     .cfi_offset 5, -8 
     movl %esp, %ebp   /* (1) */ 
     .cfi_def_cfa_register 5 
     pushl %ebx     /* (2) */ 
     subl $20, %esp   /* (3) */ 
     movl 12(%ebp), %eax 
     shrl %eax 
     movl %eax, -20(%ebp) 
     jmp  .L2 
     .cfi_offset 3, -12 

위의 디스 어셈블리 출력에서 ​​3 개의 키 라인을 식별했습니다.

(1)에서 기본 포인터가 스택 포인터로 설정됩니다. 앞에서 링크에서 제공된 정보에 따라, 이것은 스택 프레임을 설정하는 일부일뿐입니다.

(2)에서 스택에 EBX (비 휘발성 레지스터)를 저장합니다. 이렇게하면 현재 값에서 4를 뺀 ESP (EBP 제외)가 자동으로 업데이트됩니다. 이 연산 후에 EBP = ESP + 4가됩니다.

(3)에서 ESP에서 20을 뺍니다. 이 작업 후에 EBP = ESP + 24입니다.

[EBP-20]에 액세스하는 것이 안전 한 이유입니다.

희망이 도움이됩니다.

+0

와우 .. 너 내 마음을 날려 버렸어, 친구. 정말 고맙습니다!! 소원 나는 당신의 답변을 투표 할 수 있지만 신참이고 따라서 충분한 평판을 가지고 있지 않습니다 :/ – Doomztrom

+0

이것은 인텔입니다, 그래서 나는 EBP = ESP - 24, 지역 변수에서 아래로 (-) 이동하고 매개 변수에서 위쪽으로 (+)? – Doomztrom

+0

@Doomztrom :이 예제의 경우 EBP = ESP + 24입니다. 스택을 직접 그려 펜과 용지로 몇 번 작업하는 것이 좋습니다. – Sparky

1

를 사용하여 내 스택입니다 ebp은 일반적으로 프레임 포인터로 사용되고 esp은 스택 포인터입니다. 프레임 포인터 주변에 발신자의 프레임 포인터와 반송 주소가 저장됩니다. 그 차이를 설명 할 수 있습니다. 제 어셈블리에서 실제로 -4(%ebp)이 사용되었으므로 아마도 다른 ABI를 찾고있을 것입니다.하지만 스택 관리를위한 간격이 항상 있어야합니다. 하여 스택 포인터에서 차감 -20 여전히 약

-24(%ebp) 액세스 : 아마 추가로 4 바이트를 설명 할 어셈블리의 movl %esp, %ebppush,있다.

+0

movl % esp, % ebp 이후의 푸시는 추가 변수를 설명합니다. 그 점에 대해 많은 감사드립니다. 스택 관리에 대한 답변도 있습니다. 감사합니다. Olivier - 감사합니다, Passant! – Doomztrom

관련 문제