1

我有以下代码

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,而....从我那里得到什么?

4

1 回答 1

0

理论上,我们对参数或返回地址的位置一无所知。在特定架构上,我们(通常)可以通过检查一些生成的汇编器来确定特定编译器的作用。首先要检查是函数 preable。在 Intel 32 位处理器上,帧指针会在 EBP 中,并在经过 一定次数的 push 保存寄存器后设置。(特别是,在push EBP为本地框架设置 EBP 之前必须有一个。)Intel 的典型 preable 可能是:

function:
        PUSH EBP
        MOV  EBP, ESP
        SUB  ESP, n         ;   allocate space for local variables

除此之外:英特尔堆栈不断增长,英特尔的编译器几乎普遍将参数从右向左推送,因此在您的情况下,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 之前推入额外的寄存器,从而导致偏移量相应更高。这只是一种可能的布局。

于 2013-11-15T14:35:37.163 回答