Според https://docs.microsoft.com/ru-ru/cpp/build/x64-software-conventions?view=vs-2017 - xmm6:xmm15 са енергонезависими. Но програмата ми не се срива, ако не запазя xmm6, xmm7. Не извиквам ОС от сборка. Трябва ли да запазя регистрите в този случай? Работя под Windows 7.
msvc 2017 x64 запазване на регистъра
Отговори (1)
Нарушаването на ABI не гарантира грешка, точно както UB в C може да работи. напр. може би повикващият записва/възстановява (при влизане/излизане) XMM reg, който унищожавате, но не се интересува от техните стойности в извикването на вашата функция. напр. може би е искал да запази FP стойност в регистър през printf
повикване, а не през извикването на вашата функция.
Или може би нищо не ги използва и main
и кодът за стартиране на CRT не се интересуват.
Начинът, по който ABI гарантира работа, е, че ако ги следвате, гарантирате без проблеми, а не обратното.
IDK, ако има функция за обвивка „проверка“ на конвенцията за извикване, която проверява дали всички запазени за повиквания правила са запазени правилно и че не сте стъпили на пространство на стека извън пространството на сянката и (ако има такива) на вашите аргументи на стека. Сигурно някой е написал нещо подобно. напр. Писане на thunk за проверка на съответствието на SysV ABI
Би било чудесно да избягвате запазването на тези регистри, защото това влияе на производителността (не много, но все пак).
Ако компилирате вашия C с GCC или clang, можете да декларирате прототипа на вашата asm функция като използващ x86-64 System V ABI, където всички xmm0..15 са извиквани (и предаването на аргументи използва различни регистри), използвайки атрибут на GCC функция
__attribute__((sysv_abi))
extern "C" int myfunc(void);
Тогава повикващият ще трябва да запази/възстанови всички от xmm6..15, защото трябва да приеме, че извикваният ги е унищожил.
Така че направете това за функция, която е достатъчно високо в дървото на повикванията, така че тези режийни разходи да се амортизират при много извиквания на функции.
(Или по-добре, използвайте вътрешни елементи, така че използването на XMM regs да може да се вгради и да оптимизирате режийните разходи за повикване/повтаряне, както и режийните разходи за записване/възстановяване на XMM рег. Ако запазването/възстановяването или режийните разходи за повикване са от значение, решението е по-вградено, така че функциите не са толкова малки.)
Вижте Заобикаляне на Windows calling convention preserving xmm registers? за това . Внимавайте, че ICC е с грешки и не успява да запази/възстанови XMM6..15 около извикване на System V ABI функция и GCC не поддържа правилно AVX в Windows (проблеми с подравняването на стека).