gpt4 book ai didi

c - 当我们将 "cc"添加到 clobber 列表时,程序集输出中会发生什么

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

我读到,如果我们在 clobber 列表中指定“cc”,则表示汇编代码修改了标志寄存器

编写了一个示例程序来检查添加“cc”和不添加之间的区别。
比较程序集,当我们添加“cc”时没有变化。

#include <stdio.h>

int main(void)
{
unsigned long sum;

asm("incq %0"
: "=r"(sum)//output operand
: "r" (sum) //input operand
);
printf("sum= %lu\n", sum);
return 0;
}

我们什么时候应该使用“cc”,它在汇编输出中的作用是什么

最佳答案

对于 x86,绝对没有。 对于 x86 和 x86-64,一个 cc Clobber 隐含在每个 asm() 中陈述。 这个设计决定是有道理的,因为大多数 x86 指令都写了 FLAGS。而且因为它很容易错过,并且很难通过测试发现。 (尽管 GNU C 内联汇编不乏容易出错的东西。通常不需要使用它。)

(当你的 asm 语句不修改标志时,它确实无法告诉编译器,但这样做的成本可能很低,通常只需要多一条指令来重做比较或其他东西,或者保存一个变量,这样它就可以稍后比较。)

如果你想学究,你可以使用 "cc"在修改 FLAGS 的每个 asm 语句中破坏。

对于非 x86,您必须使用 cc在每个修改标志/条件代码的 asm 语句中(在具有它们的 ISA 上)。例如臂 .在 ARM 上,设置标志是可选的;带有 S 后缀设置标志的指令。所以adds r0, r1, r2根据 r0 = r1+r2 设置标志,但是 add r0, r1, r2留下旗帜不变。

如果您遗漏了 "cc" clobber(在非 x86 上),编译器可能会发出 asm,在 asm 语句之前设置标志并在之后读取它们,作为实现其他一些非 asm 语句的一部分。因此它可能与销毁寄存器本质上相同:无意义的行为取决于编译器使用寄存器或标志的详细信息,并且随优化级别和/或编译器版本而异。

这就是为什么测试不足以证明内联 asm 是安全的。使用一个编译器版本,您很容易走运并让编译器生成的代码碰巧不会在 asm 语句中的状态寄存器/条件代码中保留任何内容,但在一个函数中使用不同的编译器版本或不同的周围代码,该内联可以容易受到错误的 asm 语句的影响。

关于c - 当我们将 "cc"添加到 clobber 列表时,程序集输出中会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59656857/

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