首页 > 解决方案 > 为什么std atomic将5插入堆栈

问题描述

我想看看如何std::atomic翻译成汇编。为此,我编写了以下代码,但有些地方我不明白。

以下代码:

int main(void)
{
    std::atomic<int> a;
    a.fetch_add(0);
    return 0;
}

由 GCC 编译为:

1 |  push    rbp
2 |  mov     rbp, rsp
3 |  mov     DWORD PTR [rbp-4], 0
4 |  mov     DWORD PTR [rbp-8], 5
5 |  mov     edx, DWORD PTR [rbp-4]
6 |  lea     rax, [rbp-12]
7 |  lock xadd       DWORD PTR [rax], edx
8 |  mov     eax, 0
9 |  pop     rbp
10|  ret

为什么 GCC 将“5”(第 4 行)推入堆栈?

标签: c++assemblyg++

解决方案


如果您将 Richard Critten 非常有帮助地发布在评论中,并将 GCC 命令行更改为 use -O0,文字 5 会重新出现。引人注目的是,它也出现在

std::__atomic_base<int>::operator int() const:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 32
        ...
        mov     DWORD PTR [rbp-12], 5
        mov     eax, DWORD PTR [rbp-12]
        mov     esi, 65535
        mov     edi, eax
        call    std::operator&(std::memory_order, std::__memory_order_modifier)

所以文字5最终作为参数传递给该调用,在%edi.

既然参数是std::memory_order,我们可以查看文档并查看

typedef enum memory_order {
    memory_order_relaxed,
    memory_order_consume,
    memory_order_acquire,
    memory_order_release,
    memory_order_acq_rel,
    memory_order_seq_cst
} memory_order;

从字面上实现,它将给出memory_order_seq_cst = 5.

请注意,这memory_order_seq_cstfetch_add's ordering 参数的默认值,因此您希望看到它作为参数传递。


推荐阅读