Что обеспечивает чтение / запись операндов в нужное время с расширенным ASM?
Согласно GCCРасширенный шаблон ASM и ассемблерЧтобы инструкции оставались последовательными, они должны находиться в одном блоке ASM. У меня возникают проблемы с пониманием того, что обеспечивает планирование или время чтения и записи в операнды в блоке с несколькими операторами.
В качестве примера,EBX
или жеRBX
должен быть сохранен при использованииCPUID
потому что, согласно ABI, звонящий владеет им. Есть некоторые открытые вопросы относительно использованияEBX
а такжеRBX
поэтому мы хотим сохранить его безоговорочно (это требование). Таким образом, три инструкции должны быть закодированы в один блок ASM, чтобы обеспечить последовательность инструкций (относительно шаблона ассемблера, описанного в первом абзаце):
unsigned int __FUNC = 1, __SUBFUNC = 0;
unsigned int __EAX, __EBX, __ECX, __EDX;
__asm__ __volatile__ (
"push %ebx;"
"cpuid;"
"pop %ebx"
: "=a"(__EAX), "=b"(__EBX), "=c"(__ECX), "=d"(__EDX)
: "a"(__FUNC), "c"(__SUBFUNC)
);
Если выражение, представляющее операнды, интерпретируется в неправильный момент времени, то__EBX
будет сохраненEBX
(а неCPUID
«sEBX
), который, вероятно, будет указателем на Глобальную таблицу смещений (GOT), если включен PIC.
Где именно выражение указывает, что хранилищеCPUID
«s%EBX
в__EBX
должно произойти (1) послеPUSH %EBX
; (2) послеCPUID
; но (3) доPOP %EBX
?