我正在尝试以下内联汇编的示例:http: //www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html 但是有些事情让我对破坏感到困惑:
- 关于 clobber 的行为
Clobbering 本质上是告诉 GCC 不信任指定寄存器/内存中的值。“好吧,当 GCC 可以准确地知道你在之前和之后对寄存器做了什么时,它真的很有帮助......它甚至足够聪明地知道如果你告诉它把 (x+1) 放在一个寄存器中,那么如果你不破坏它,然后 C 代码引用 (x+1),并且它能够保持该寄存器空闲,它将重用计算。唷。”
教程中关于clobber列表的一些不一致之处:
对于输入/输出列表中指定的寄存器,不需要像GCC所知的那样将它们放入clobber列表中;但是在关于 rep_movsl(或 rep_stosl)的示例中:asm ("cld\n\t" "rep\n\t" "stosl" : /* 没有输出寄存器 */ : "c" (count), "a" (fill_value), "D" (dest) : " %ecx", "%edi" );
尽管“S,D,c”在输出操作数中,但它们再次被列为clobbered。我在 C 中尝试了一个简单的片段:
#include<stdio.h>
int main()
{
int a[] = {2, 4, 6};
int b[3];
int n = 3;
int v = 12;
asm ("cld\n\t"
"rep\n\t"
"movsl"
:
: "S" (a), "D" (b), "c" (n)
: );
// : "%ecx", "%esi", "%edi" );
printf("%d\n", b[1]);
}
如果我使用注释掉的clobber 列表,GCC 会抱怨:
ac:8:3: 错误: 在重新加载 'asm' 时找不到类 'CREG' 中的寄存器 ac:8:3: 错误: 'asm' 操作数有不可能的约束
如果我使用空的clobber列表,它将编译并且输出为4。