Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用clang编译内联程序集时分配的寄存器冲突_Clang_Inline Assembly_Compiler Bug - Fatal编程技术网

使用clang编译内联程序集时分配的寄存器冲突

使用clang编译内联程序集时分配的寄存器冲突,clang,inline-assembly,compiler-bug,Clang,Inline Assembly,Compiler Bug,考虑以下示例程序(针对Linux/x86-64): (因此,edx中的arg1,eax中的arg2) 但是,使用Clang编译(在6.0和10.0上确认)会导致为arg1和arg2分配相同的寄存器: 401174: e8 d7 fe ff ff callq 401050 <strtoul@plt> 401179: 44 89 f0 mov %r14d,%eax ; <-- 40117c:

考虑以下示例程序(针对Linux/x86-64):

(因此,edx中的arg1,eax中的arg2)

但是,使用Clang编译(在6.0和10.0上确认)会导致为arg1和arg2分配相同的寄存器:

  401174:       e8 d7 fe ff ff          callq  401050 <strtoul@plt>
  401179:       44 89 f0                mov    %r14d,%eax ; <--
  40117c:       89 c1                   mov    %eax,%ecx
  40117e:       01 c0                   add    %eax,%eax ; <-- so, arg1 and arg2 both in eax
  401180:       01 c1                   add    %eax,%ecx
  401182:       91                      xchg   %eax,%ecx
401174:e8 d7 fe ff ff callq 401050

401179:4489F0MOV%r14d%eax;看来叮当声把我搞错了。您是否有理由认为需要枚举寄存器而不仅仅是使用
“+r”
?这似乎工作正常。只需添加:如果您同时为arg1和arg2指定
“+a”
,则Clang允许使用它,这在本例中显然是不可能的。gcc将其视为“不可能的约束”而拒绝。或者您在约束中为ecx指定了一个值(这将阻止它在
r
的其他术语中使用),或者您在asm中覆盖它并需要对其进行删除(这也将阻止它在其他术语中使用)。使用
r
时,叮当声似乎是正确的。如果您枚举寄存器,这只是一个问题,它显然假定显式列表覆盖了其他检查(是的,这似乎是错误的)。似乎您只是希望
“+r”
能够避免ECX,因为有时需要它作为某些指令的固定寄存器(如变量计数
shl
)。按照这种逻辑,它应该避免每个寄存器,也许EBP除外——它们都有一些隐含的用途。如果您的特定asm模板需要,只需要求您在ECX中输入一个值,或在ECX或任何其他寄存器中声明一个clobber,就更明智了,当你向编译器描述你的代码时,不要试图让某些寄存器变得安全,但这与你看到的实际错误行为是不同的。您的LLVM错误报告是有效的,这是一个真正的错误。2个独立的输出需要在不同的寄存器中,即使它们也是已知具有相同输入值的输入。GCC和LLVM不尝试解析asm模板字符串,只是盲目地填写
%stuff
,所以它不依赖于哪个指令。像
“nop#arg1=%0,arg2=%1”
这样的模板并查看编译器的
-s
asm输出就足够了。(并且比拆卸时更整洁)。
    11bf:       e8 cc fe ff ff          callq  1090 <strtoul@plt>
    11c4:       89 da                   mov    %ebx,%edx
    11c6:       89 d1                   mov    %edx,%ecx
    11c8:       01 c2                   add    %eax,%edx
    11ca:       01 c1                   add    %eax,%ecx
    11cc:       91                      xchg   %eax,%ecx
  401174:       e8 d7 fe ff ff          callq  401050 <strtoul@plt>
  401179:       44 89 f0                mov    %r14d,%eax ; <--
  40117c:       89 c1                   mov    %eax,%ecx
  40117e:       01 c0                   add    %eax,%eax ; <-- so, arg1 and arg2 both in eax
  401180:       01 c1                   add    %eax,%ecx
  401182:       91                      xchg   %eax,%ecx