2013-06-17 3 views
1

Во многих примерах, когда я скомпилирую c-функцию (например, сортировку оболочки алгоритма сортировки), stackaddress (i gues называется?) Ebp-4/-4 (% ebp)/[ebp] -4 или что-то еще, который, как я понимаю, обычно используется для первой локальной переменной, в моем случае не используется.intel x86 - почему -4 (% ebp) ничего не значит?

Так что мне было интересно, знает ли кто-то, для чего он используется, поскольку он не используется ни для каких локальных переменных, ни для чего другого.

Кроме того, 20 вычитается из указателя стека, чтобы выделить пространство стека для переменных языка - но тогда значение сохраняется до -24 (% ebp) - как это возможно, когда есть только занятая комната до -20 ??

с-функция 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; 
     } 
    } 
} 

И это мой стек с помощью gcc -S 32-битной Ubuntu

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 (энергонезависимый регистр) в стек. Это автоматически обновляет ESP (но не EBP), вычитая четыре из его текущего значения. Обратите внимание, что после этой операции EBP = ESP + 4.

В (3) мы вычитаем 20 из ESP. После этой операции EBP = ESP + 24.

Вот почему безопасно осуществлять доступ к [EBP-20].

Надеюсь, это поможет.

+0

ничего себе .. ты просто взорвал мой разум, чувак. Спасибо большое!! Жаль, что я мог бы проголосовать за ваши ответы, но я новичок и поэтому не имею достаточной репутации:/ – Doomztrom

+0

За исключением того, что это intel, поэтому я думаю, что это EBP = ESP-24, перемещение вниз (-) в локальных переменных и вверх (+) в параметрах? – Doomztrom

+0

@ Doomztrom: Для этого примера это EBP = ESP + 24. Я рекомендую рисовать себе стек и работать с ним с помощью ручки и бумаги несколько раз. – Sparky

1

На x86 ebp обычно используется в качестве указателя кадра, а esp - указатель стека. Вокруг указателя кадра сохраняется указатель кадра вызывающего и обратный адрес. Это может объяснить пробел. В моей сборке фактически используется -4(%ebp), поэтому, возможно, мы смотрим на другой ABI, но всегда должно быть пробел для администрирования стека.

-20 О вычитают из указателя стека и получить доступ -24(%ebp): есть, вероятно, push после movl %esp, %ebp в сборке, которая будет приходиться на дополнительные 4 байта.

+0

Ну, толчок после movl% esp,% ebp объяснил бы дополнительную переменную. Большое спасибо за это. А также ответ на администрирование стека !! Спасибо, Оливье, спасибо вам, Пассант! – Doomztrom

Смежные вопросы