Проводник компилятора и G CC имеют разные выходы - PullRequest
0 голосов
/ 02 февраля 2020

У меня есть некоторый C код, который при передаче в Compiler Explorer выводит:

        mov     BYTE PTR [rbp-4], al
        mov     eax, ecx
        mov     BYTE PTR [rbp-8], al
        mov     eax, edx
        mov     BYTE PTR [rbp-12], al

Однако, если я использую G CC или G ++, он дает мне следующее:

        mov     BYTE PTR 16[rbp], al
        mov     eax, edx
        mov     BYTE PTR 24[rbp], al
        mov     eax, ecx
        mov     BYTE PTR 32[rbp], al

Понятия не имею, почему значения BYTR отличаются. У них совершенно неправильный адрес, и я не понимаю, почему они находятся перед частью [rdp].

Если вы знаете, как воспроизвести первый вывод, используя g cc или g ++, пожалуйста, помогите!

1 Ответ

1 голос
/ 03 февраля 2020

g cc .exe (G CC) 8.2.0

Похоже, G CC для соглашения о вызовах Windows x64 использует теневое пространство ( 32 байта выше адреса возврата), зарезервированного его вызывающей стороной. Godbolt G CC устанавливает целевой GNU / Linux, то есть x86-64 System V ABI.

Вы можете получить тот же код на Godbolt, пометив свою функцию __attribute__((ms_abi)). Конечно, это означает, что ваш вызывающий должен видеть этот атрибут в прототипе, чтобы он знал, как зарезервировать это пространство и какие регистры для передачи аргументов функций.

Соглашение о вызовах Windows x64 в большинстве случаев хуже, чем x86- 64 Система V; например, меньше регистров передачи аргументов. Одним из его единственных преимуществ является более простая реализация функций variadi c (из-за теневого пространства) и наличие некоторых XMM-регистров с сохранением вызовов. (Вероятно, слишком много, но в x86-64 SysV есть ноль.) Поэтому более вероятно, что вы захотите использовать кросс-компилятор (нацеленный на GNU / Linux) на Windows или использовать __attribute__((sysv_abi)) для всех ваших функций. (https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html)

XMM-часть соглашения о вызовах обычно не имеет значения для кода ядра; большинство ядер избегают сохранения / восстановления состояния SIMD / FPU при входе / выходе из ядра, не позволяя компилятору использовать инструкции SIMD / FP.

...