简体   繁体   English

__asm __volatile 如何执行?

[英]How does __asm __volatile execute?

gcc_inline void
lcr0(uint32_t val)
{
    __asm __volatile("movl %0,%%cr0" : : "r" (val));
}

In the above code, I'm not sure where val is inserted into the assembly string.在上面的代码中,我不确定将 val 插入到程序集字符串的何处。 Does val replace the %c in the string? val 是否替换字符串中的 %c?

If possible can someone clarify what : : "r" does as well?如果可能的话,有人可以澄清: : "r"作用吗?

"r" means you are specifying %0 to be a register (as an input). "r"表示您将%0指定为寄存器(作为输入)。 (val) means you are specifying that the register should contain the value of val . (val)表示您指定寄存器应包含val的值。 So the compiler will allocate a register and make sure it contains val .因此编译器将分配一个寄存器并确保它包含val For x86_64 the first argument for the function will be in %edi / %rdi , and that is what %0 will expand to.对于 x86_64,函数的第一个参数将在%edi / %rdi ,这就是%0将扩展到的。


I stand corrected...我站纠正...

...if the function is not inlined , val will be passed in edi / rdi but might be shuffled around before the asm , but the "r" will cause the compiler to arrange for it to be in some register for the asm . ...如果该函数没有内联,则val将在edi / rdi传递,但可能会在asm之前混洗,但"r"将导致编译器将其安排在asm某个寄存器中。 (See the effect of -O0, below). (请参阅下面的 -O0 的效果)。

Also a function which is not declared/defined to be inline may be inlined, at higher levels of optimization.此外,未声明/定义为内联的函数也可以在更高级别的优化中内联。

I note that it is only possible to read/write CR0 to/from a general purpose register and then only at privilege level 0. @PeterCordes notes that a "memory" clobber would probably a Good Idea.我注意到只能从通用寄存器读取/写入CR0 ,然后只能在特权级别 0。@PeterCordes 指出"memory"破坏可能是一个好主意。 Clearly, changing CR0 can have really exciting side effects !显然,改变CR0会产生非常令人兴奋的副作用!


When I tried this at -O0 I found that a simple inline was ignored, and the function compiled for x86_64 to:当我在-O0尝试此操作时,我发现忽略了一个简单的inline ,并且为 x86_64 编译的函数为:

   lcr0:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    %edi, -4(%rbp)
        movl    -4(%rbp), %eax
        movl %eax,%cr0
        nop
        popq    %rbp
        ret

I guess that gcc_inline may include __attribute__((__always_inline__)) , in which case even at -O0 lcr0 is inlined -- but with lots of lovely stack business.我猜gcc_inline可能包括__attribute__((__always_inline__)) ,在这种情况下,即使在-O0 lcr0也是内联的——但是有很多可爱的堆栈业务。 This time for x86:这次是 x86:

  main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $16, %esp
        movl    12(%ebp), %eax
        movl    (%eax), %eax
        movl    (%eax), %eax
        movl    %eax, -4(%ebp)
        movl    -4(%ebp), %eax
        movl    %eax, -8(%ebp)
        movl    -8(%ebp), %eax
        movl %eax,%cr0
        nop
        movl    $0, %eax
        leave
        ret

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM