了解基指针和堆栈指针:在 gcc 输出的上下文中

2024-01-09

我有以下 C 程序:

int main()
{
    int c[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2};
    return c[0];
}

当使用 gcc 的 -S 指令编译时,我得到以下程序集:

    .file   "array.c"
    .text
.globl main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $0, -48(%rbp)
    movl    $0, -44(%rbp)
    movl    $0, -40(%rbp)
    movl    $0, -36(%rbp)
    movl    $0, -32(%rbp)
    movl    $0, -28(%rbp)
    movl    $0, -24(%rbp)
    movl    $0, -20(%rbp)
    movl    $1, -16(%rbp)
    movl    $2, -12(%rbp)
    movl    -48(%rbp), %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (GNU) 4.4.5 20110214 (Red Hat 4.4.5-6)"
    .section        .note.GNU-stack,"",@progbits

我不明白的是为什么前面的数组元素离 bp 更远?看起来数组上的元素几乎是以相反的顺序放置的。

另外为什么 gcc 不使用 push 而不是 movl 将数组元素压入堆栈?


不同的观点

将数组作为静态变量移动到全局命名空间到我得到的模块:

    .file   "array.c"
    .data
    .align 32
    .type   c, @object
    .size   c, 40
c:
    .long   0
    .long   0
    .long   0
    .long   0
    .long   0
    .long   0
    .long   0
    .long   0
    .long   1
    .long   2
    .text
.globl main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    c(%rip), %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (GNU) 4.4.5 20110214 (Red Hat 4.4.5-6)"
    .section    .note.GNU-stack,"",@progbits

使用以下 C 程序:

static int c[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2};

int main() 
{
    return c[0];
}

这并没有让我们对堆栈有更多的了解。但有趣的是,使用稍微不同的语义看到汇编的不同输出。


首先,x86堆栈向下增长。按照惯例,rbp存储原始值rsp。因此,函数的参数位于positive相对于的偏移量rbp,其自动变量位于negative偏移量。自动数组的第一个元素的地址低于所有其他元素,因此距离最远rbp.

这是出现的一个方便的图表在本页 http://unixwiz.net/techtips/win32-callconv-asm.html:

我看不出编译器为什么couldn't使用一系列push初始化数组的说明。我不确定这是否是一个好主意。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

了解基指针和堆栈指针:在 gcc 输出的上下文中 的相关文章

随机推荐