c - intel x86 - 为什么 -4(%ebp) 没有任何意义?

标签 c assembly compilation x86 stack

在许多示例中,当我编译一个 c 函数(例如排序算法 shell sort)时,stackaddress(我猜它被调用了?)ebp-4/-4(%ebp)/[ebp]-4 或其他,据我所知,通常用于第一个局部变量,在我的例子中没有使用。

所以我想知道是否有人知道它的用途,因为它不用于任何局部变量或与此相关的任何其他内容。

此外,从堆栈指针中减去 20 以为语言环境变量分配堆栈空间 - 但随后仍将值保存到 -24(%ebp) - 只有在 -20 之前才腾出空间时,这怎么可能? ?

C 函数如下所示:

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

提前致谢:)

最佳答案

您的问题分为两部分。

据我了解,第一个与 [EBP-4] 的用途有关。为此,我建议您在 What is stack frame in assembly? 阅读 x86 堆栈框架的摘要。 .

要正确回答问题的整个 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(非 volatile 寄存器)保存到堆栈中。这会自动更新 ESP(但不是 EBP),从其当前值中减去四。请注意,经过此操作后,EBP = ESP + 4。

在 (3) 处,我们从 ESP 中减去 20。这样操作后,EBP = ESP + 24。

这就是为什么访问 [EBP-20] 是安全的。

希望这对您有所帮助。

关于c - intel x86 - 为什么 -4(%ebp) 没有任何意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17146506/

相关文章:

c - 在汇编代码中查找结构变量的值

linux - 在 shellcode NASM 的 JMP CALL POP 技术中避免 JMP?

python - 如何将多个 py 文件编译为一个文件?

c - 使用 free 理解 malloc 和指针递增

c - 如何编写可在多硬件平台上运行的可配置嵌入式 C 代码

c++ - 什么是 IACA,我该如何使用它?

linux - 我可以运行从更高版本的 gcc 编译的二进制文件吗?

编译没有主要功能的C代码

c - 设置GNSDK开发环境-nmake不起作用

c - C中的双指针const正确性警告