clang __asm__在case statment中使用标签,得到错误:指令操作数无效。

问题描述 投票:0回答:1

我正在尝试添加 labelsC 源码(仪器仪表);有一点汇编经验,comipler是 clang; 我有一个奇怪的行为与 __asm__ 和标签 CASE 报表!!!;这是我试过的。

// Compiles successfully.
int main()
{
     volatile unsigned long long a = 3;
      switch(8UL)
      {
         case 1UL:
            //lbl:;
            __asm__ ("movb %%gs:%1,%0": "=q" (a): "m" (a));
            a++;
      }
    return 0;
}

还有这个:

// Compiles successfully.
int main()
{
     volatile unsigned long long a = 3;
      switch(8UL)
      {
         case 1UL:
            lbl:;
            //__asm__ ("movb %%gs:%1,%0": "=q" (a): "m" (a));
            a++;
      }
    return 0;
}

命令。

 clang -c examples/a.c
examples/a.c:5:14: warning: no case matching constant switch condition '8'
      switch(8UL)
             ^~~
1 warning generated.                  

但是这个:

// not Compile.
int main()
{
     volatile unsigned long long a = 3;
      switch(8UL)
      {
         case 1UL:
            lbl:;
            __asm__ ("movb %%gs:%1,%0": "=q" (a): "m" (a));
            a++;
      }
    return 0;
}

错误。

             ^~~
examples/a.c:9:22: error: invalid operand for instruction                                                                                                                                     
            __asm__ ("movb %%gs:%1,%0": "=q" (a): "m" (a));
                     ^
<inline asm>:1:21: note: instantiated into assembly here                                                                                                                                      
        movb %gs:-16(%rbp),%rax
                           ^~~~
1 warning and 1 error generated. 

我使用的是.NET技术。

clang --version
clang version 9.0.0-2 (tags/RELEASE_900/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

重要的是,这将成功地编译与 gcc.

gcc --version
gcc (Ubuntu 9.2.1-9ubuntu2) 9.2.1 20191008
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

我在Ubuntu 19上工作,64 BIT.任何帮助,请。


编辑

根据下面公认的答案。

  • __asm__ 语句本身会导致错误(大小不同)。
  • 语句本身会造成错误(大小不同)。__asm__ 是不可及的。
  • 在语句中添加Label使其可到达。
  • GCC 忽略它。
  • Clang 不忽略它。
clang x86-64 inline-assembly att
1个回答
2
投票

movb 是8位操作数大小。%rax 是64位的,因为你用了 unsigned long long. 只要用 mov 来进行与输出变量相同宽度的加载,或者使用 movzbl %%gs:%1, %k0 到零扩展到64位。 (明确地用 movzbl通过写入64位寄存器的32位低半部分,隐含到64位。k 的修饰语 %k0))

奇怪的是,GCC居然没有把它也拒之门外;也许GCC把它作为死代码删除是因为无法到达 caseswitch(8). 如果你看GCC的asm输出,它可能不包含该指令。

© www.soinside.com 2019 - 2024. All rights reserved.