繁体   English   中英

GCC内联ASM保证

[英]GCC inline ASM guarantees

我认为这是一个简单的问题,但我什么也找不到。 如果我写

void bar()
{
    {
        void *rax = 0/* ...*/, *rbx = 0/* ... */;
        asm volatile ("movq %0, %%rax; movq %1, %%rbx;" : : "m"(rax), "m"(rbx));
        goto foo;    
    }

    {
        foo:
        void* rax, *rbx;
        asm volatile ("movq %%rax, %0; movq %%rbx, %1;" : "=m"(rax), "=m"(rbx));

        // LOTS OF CODE
    }
}

是否可以确保在运行第二个块中的任何其他代码之前可以获取rax / rbx的值?

否-编译器根据约束将其in / out值连接到在asm语句之前/之后立即分配的寄存器/内存位置,并假定其他寄存器不受影响。 因此,在您的情况下,它可能已将重要内容放入您正在破坏的%%eax%%ebx中(这可能导致崩溃或其他不良行为)。

每当您在asm语句中使用固定寄存器时,都必须在clobbers列表中列出这些寄存器(除非您使用的是映射到特定寄存器的约束)。 因此,至少您需要:

asm volatile ("movq %0, %%rax; movq %1, %%rbx;" : : "m"(rax), "m"(rbx) : "rax", "rbx");

为您的asm语句-但是即使这样,也无法保证编译器不会在您的第一个asm块之后和第二个asm块之前(%s试图保存的值)在%%eax%%ebx放入其他内容。

在gcc中将volatileasm一起使用将确保编译器不会重新排序状态。 但是,不能保证编译器不会在foo:标签和内联asm语句之间添加额外的代码。 当然,这意味着您不能依赖该部分中保留的寄存器值-我还没有提供一个独特的示例,但是我敢肯定编译器不保证这样做可以不会发生

暂无
暂无

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

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