gpt4 book ai didi

c++ - 内联 assembly 约束修饰符 = 和 +

转载 作者:搜寻专家 更新时间:2023-10-30 23:59:22 27 4
gpt4 key购买 nike

我写了一个包含内联汇编代码的简单程序。我的代码简单地添加变量 a 和 b 并返回结果为 b。

令我困惑的是为什么下面的代码会生成这条指令 movl 28(%esp), %ecx.

我没有完全理解修饰符 + 和 = 在输入和输出列表中的作用。因此,如果您能对此有所说明,我们将不胜感激。

#include <cstdio>

int main( int argc , char ** argv )
{
int a = 2, b = 7;

__asm__
(
"addl %1,%0;"
:"+r"(b)
:"r"(a), "r"(b)
);

printf("b = %d\n",b);

return 0;
}
    movl    $2, 24(%esp)
movl $7, 28(%esp)

movl 24(%esp), %edx
movl 28(%esp), %ecx
movl 28(%esp), %eax

addl %edx,%eax

movl %eax, 28(%esp)

我接下来要展示的是错误的。但这是为了让我更好地了解 GCC 中正在发生的事情。

好的,现在我从 +r 更改为 =r。这是 GCC 生成的汇编代码。

#include <cstdio>

int main( int argc , char ** argv )
{
int a = 2, b = 7;

__asm__
(
"addl %1,%0;"
:"=r"(b)
:"r"(a), "r"(b)
);

printf("b = %d\n",b);

return 0;
}
    movl    $2, 24(%esp)
movl $7, 28(%esp)
movl 24(%esp), %eax
movl 28(%esp), %edx

addl %eax,%eax;

movl %eax, 28(%esp)

现在输出是 4,这是错误的。我的问题是为什么使用“=r”GCC 决定为 b 重用寄存器 eax,如下所示这条指令 addl %eax,%eax;

最佳答案

What is confusing me is why the code below generates this instruction movl 28(%esp), %ecx

因为您已将 b 列为两个独立的输入寄存器;第一节中的+ 表示程序集读取和修改寄存器。所以它被加载到两个寄存器中,即使程序集不使用第二个。

程序集应该是:

"addl %1,%0;" : "+r"(b) : "r"(a)

I don't fully undertand the roles the modifiers + and = play in the input and output lists.

+ 表示寄存器被读取和写入,因此在汇编开始之前它必须具有变量的值。 =表示刚写入,在汇编前可以取任意值。

参见 documentation了解全部详情。

My question is why with "=r" GCC decided to use the register eax for b as shown in this instruction addl %eax,%eax;

因为现在你的约束是错误的。您告诉编译器您只写入 addl 指令的第二个操作数 (%0),因此它假定它可以使用与以下之一相同的寄存器输入。事实上,该操作数也是 addl 的输入。然后你仍然告诉它你需要 b 的第二个拷贝在程序集不使用的单独寄存器中。

正如我上面所说,在第一个(输出)列表中使用 "+r"(b) 来指示 %0b 用于输入和输出,第二个(输入)列表中的 "r"(a) 表示 %1a 并且仅用于输入。不要放入第三个寄存器,因为程序集中没有 %2

关于c++ - 内联 assembly 约束修饰符 = 和 +,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16695415/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com