У меня есть следующий код
int isBST(struct node* node)
{
return(isBSTUtil(node, INT_MIN, INT_MAX));
}
int isBSTUtil(struct node* node, int min, int max)
{
if (node==NULL)
return 1;
if (node->data <= min || node->data > max)
return 0;
return
isBSTUtil(node->left, min, node->data) && // Allow only distinct values
isBSTUtil(node->right, node->data, max); // Allow only distinct values
}
Когда я отлаживаю код в GDB, я вижу, что второй параметр установлен по адресу ebp + 0xc (0xbffff188 + 0xc), третий параметр установлен в ebp + 0x10, и первый параметр неясен, где, в теории, мы знаю, что адрес возврата функции находится в EBP + 4, первый параметр находится в EBP +8 и …. откуда у меня так?
В теории мы ничего не знаем о том, где аргументы или
обратный адрес находится. На конкретной архитектуре мы
может (обычно) выяснить, что делает конкретный компилятор
исследуя некоторые из сгенерированных ассемблера. первый вещь для
исследовать является функцией preable. На 32-битном процессоре Intel
указатель кадра будет в EBP, и он будет настроен после
определенное количество нажатий для сохранения регистров. (Особенно,
должен быть push EBP
до того, как EBP настроен для местного
кадр.) Типичным preable для Intel может быть:
function:
PUSH EBP
MOV EBP, ESP
SUB ESP, n ; allocate space for local variables
Помимо этого: стек Intel растет и компиляторы
для Intel почти повсеместно выдвигают аргументы
слева, так что в вашем случае, max
будет иметь самый высокий адрес,
min
будет прямо под ним, и node
ниже этого. Так что ваши
Изображение рамки будет:
[EBP - ...] local variables
[EBP + 0] the pushed old EBP
[EBP + 4] the return address
[EBP + 8] the first argument (node)
[EBP + 12] the second argument (min)
[EBP + 16] the third argument (max)
(Предполагается, что все аргументы являются 32-битными значениями.)
Конечно, компилятор может выдвинуть дополнительные регистры, прежде чем
нажав EBP, в результате чего смещения будут соответственно выше.
Это только один из возможных вариантов размещения.
Других решений пока нет …