What ensures reads/writes of operands occurs at desired timed with extended ASM?

后端 未结 2 1628
一个人的身影
一个人的身影 2020-12-19 23:56

According to GCC\'s Extended ASM and Assembler Template, to keep instructions consecutive, they must be in the same ASM block. I\'m having trouble understanding what provide

2条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-20 00:17

    I think you understand, but to be clear, the "consecutive" rule means that this:

    asm ("a");
    asm ("b");
    asm ("c");
    

    ... might get other instructions interposed, so if that's not desirable then it must be rewritten like this:

    asm ("a\n"
         "b\n"
         "c");
    

    ... and now it will be inserted as a whole.


    As for the cpuid snippet, we have two problems:

    1. The cpuid instruction will overwrite ebx, and hence clobber the data that PIC code must keep there.

    2. We want to extract the value that cpuid places in ebx while never returning to compiled code with the "wrong" ebx value.

    One possible solution would be this:

    unsigned int __FUNC = 1, __SUBFUNC = 0;
    unsigned int __EAX, __EBX, __ECX, __EDX;
    
    __asm__ __volatile__ (    
      "push %ebx;"
      "cpuid;"
      "mov %ebx, %ecx"
      "pop %ebx"
      : "=c"(__EBX)
      : "a"(__FUNC), "c"(__SUBFUNC)
      : "eax", "edx"
    );
    __asm__ __volatile__ (    
      "push %ebx;"
      "cpuid;"
      "pop %ebx"
      : "=a"(__EAX), "=c"(__ECX), "=d"(__EDX)
      : "a"(__FUNC), "c"(__SUBFUNC)
    );
    

    There's no need to mark ebx as clobbered as you're putting it back how you found it.

    (I don't do much Intel programming, so I may have some of the assembler-specific details off there, but this is how asm works.)

提交回复
热议问题