O que garante que leituras / gravações de operandos ocorram no tempo desejado com o ASM estendido?
De acordo com o GCCModelo estendido de ASM e Assembler, para manter as instruções consecutivas, elas devem estar no mesmo bloco ASM. Estou tendo problemas para entender o que fornece o agendamento ou horários de leituras e gravações para os operandos em um bloco com várias instruções.
Como um exemplo,EBX
ouRBX
precisa ser preservado ao usarCPUID
porque, de acordo com a ABI, o chamador é o proprietário. Existem algumas questões em aberto com relação ao uso deEBX
eRBX
, então queremos preservá-lo incondicionalmente (é um requisito). Portanto, três instruções precisam ser codificadas em um único bloco ASM para garantir a consecutividade das instruções (re: o modelo do assembler discutido no primeiro parágrafo):
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)
);
Se a expressão que representa os operandos for interpretada no momento errado, então__EBX
será o salvoEBX
(e não oCPUID
éEBX
), que provavelmente será um ponteiro para a Global Offset Table (GOT) se o PIC estiver ativado.
Onde, exatamente, a expressão especifica que o armazenamento deCPUID
é%EBX
para dentro__EBX
deve acontecer (1) após oPUSH %EBX
; (2) após oCPUID
; mas (3) antes daPOP %EBX
?