gpt4 book ai didi

c++ - 为什么发出空的 asm 命令会交换变量?

转载 作者:行者123 更新时间:2023-12-03 12:20:56 24 4
gpt4 key购买 nike

所以我在搞内联汇编并使用 编译它海湾合作委员会 9 .
结果是交换了两个变量 a 和 b,而没有实际发出任何直接命令。

#include<cstdio>
int main(){
int a(1),b(2),c(3);
asm ("": "=r"(c):"r"(a));
asm ("": "=r"(a):"r"(b));
asm ("": "=r"(b):"r"(c));
printf("%d %d %d", a,b,c);
}

有人可以解释这里发生了什么吗?

最佳答案

变量分配的基本随机机会。 (或者实际上是 GCC 内部机器的首选)。

您使用了仅输出 "=r" asm 操作数,但是您的 asm 模板实际上并没有写入该寄存器,因此您可以获得 GCC 选择的寄存器中的任何值。

这很像使用未初始化变量的 C 未定义行为。

要查看发生了什么,将 asm 注释放在可扩展的 asm 模板中 %0%1 在 asm 注释内的模板内。这不会对 GCC 如何进行寄存器分配产生影响:它不关心模板是否使用它隐式或显式选择的寄存器;您可以编写一个有用的模板并将其与操作数约束相匹配。

将您的代码放在 Godbolt compiler explorer, with gcc9.2 -O3 -fverbose-asm :

.intel_syntax noprefix
.LC0:
.string "%d %d %d"
main:
sub rsp, 8 #,
mov edi, OFFSET FLAT:.LC0 #,
xor eax, eax #
mov ecx, 1 # tmp87,
mov esi, 2 # tmp89,
nop #ecx ecx # c, tmp87
nop #esi esi # a, tmp89
nop #edx ecx # b, c
call printf #
xor eax, eax #
add rsp, 8 #,
ret

(我把评论放在 NOP 指令上,而不是一个简单的 asm 注释,比如 asm ("nop #%0 %1": "=r"(c):"r"(a));所以编译器浏览器过滤不会删除它们。 asm 模板在将其提供给汇编程序之前是纯文本替换,因此这仍然与 GCC 使用相同选项编译原始源代码的方式完全相同。)

在前两种情况下,gcc 决定为输出选择与输入相同的寄存器,因此这些寄存器恰好像赋值一样工作。

在第三种情况下, c已经在一个寄存器中,并放了一个 3任何地方都被优化掉了,因为 "=r"(c)在读取之前覆盖该值。

也许您在编译时禁用了优化?你也可以这样做,然后跟随发生的事情。 (可能 GCC 每次都会为输入和输出选择 eax)。我通常不会费心查看反优化 -O0 asm 因为它充满了存储/重新加载噪音。

关于c++ - 为什么发出空的 asm 命令会交换变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58679320/

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