14

考虑以下示例:

struct vector {
    int  size() const;
    bool empty() const;
};

bool vector::empty() const
{
    return size() == 0;
}

生成的汇编代码vector::empty(通过 clang,经过优化):

push    rax
call    vector::size() const
test    eax, eax
sete    al
pop     rcx
ret

为什么要分配堆栈空间?它根本不使用。和可以省略pushpopMSVC 和 gcc 的优化构建也为此函数使用堆栈空间(参见Godbolt),所以一定有原因。

4

1 回答 1

11

它分配堆栈空间,因此堆栈是 16 字节对齐的。它是必需的,因为返回地址占用 8 个字节,所以需要额外的 8 个字节空间来保持堆栈 16 字节对齐。

对于某些编译器,可以使用命令行参数配置堆栈帧的对齐方式。

  • MSVC文档说堆栈始终是 16 字节对齐的。没有命令行参数可以改变这一点。Godbolt 示例显示rsp在函数开头减去了 40 个字节,这意味着其他因素也会影响这一点。
  • clang:该-mstack-alignment选项指定堆栈对齐方式。似乎默认值为 16,尽管没有记录。如果将其设置为 8,堆栈分配(pushpop)将从生成的汇编代码中消失。
  • gcc:该-mpreferred-stack-boundary选项指定堆栈对齐方式。如果给定值为 N,则表示 2^N 字节对齐。默认值为 4,即 16 个字节。如果将其设置为 3(即 8 个字节),堆栈分配(subaddfor rsp)将从生成的汇编代码中消失。

查看godbolt

于 2020-01-07T23:28:53.527 回答