Почему std atomic вставляет 5 в стек - PullRequest
4 голосов
/ 19 июня 2019

Я хотел посмотреть, как 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) в стек?

1 Ответ

4 голосов
/ 19 июня 2019

Если вы возьмете на себя полезную ссылку Ричарда Криттена (Richard Critten), очень услужливо размещенную в комментарии, и измените командную строку GCC на использование -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_cst является значением по умолчанию для параметра упорядочения fetch_add, поэтому вы ожидаете увидеть его в качестве аргумента.

...