Clang 在case station中使用标签发出叮当声,获取错误:指令的操作数无效

Clang 在case station中使用标签发出叮当声,获取错误:指令的操作数无效,clang,x86-64,inline-assembly,att,Clang,X86 64,Inline Assembly,Att,我试图在C源代码(仪器)中添加标签;comipler有一点组装经验,他是clangg;我对\uu asm\uu和CASE语句中的标签有一种奇怪的行为!!!; 以下是我尝试过的: // Compiles successfully. int main() { volatile unsigned long long a = 3; switch(8UL) { case 1UL: //lbl:; __asm

我试图在
C
源代码(仪器)中添加
标签
;comipler有一点组装经验,他是
clangg
;我对
\uu asm\uu
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. 
重要的;这将使用
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位。 请帮忙


编辑

根据以下公认的答案:

  • 语句本身会导致错误(大小不同)。
  • \uuuu asm\uuuu
    无法访问。
  • 将标签添加到语句中可以访问该语句。
  • GCC
    忽略它。
  • Clang
    不会忽略它。

    • movb
      是8位操作数大小,
      %rax
      是64位,因为您使用了
      无符号长
      。只需使用
      mov
      执行与输出变量相同宽度的加载,或使用
      movzbl%%gs:%1,%k0
      将零扩展到64位。(通过
      movzbl
      显式转换为32位,通过写入64位寄存器的32位低位半(
      %k0
      中的
      k
      修饰符)隐式转换为64位)


      令人惊讶的是,GCC也没有拒绝这一点;可能是由于
      开关(8)
      中的不可访问的
      大小写
      ,GCC将其作为死代码删除。如果查看GCC的asm输出,它可能不包含该指令。

      movb
      是8位操作数大小,
      %rax
      是64位,因为您使用了
      无符号长
      。只需使用
      mov
      执行与输出变量相同宽度的加载,或使用
      movzbl%%gs:%1,%k0
      将零扩展到64位。(通过
      movzbl
      显式转换为32位,通过写入64位寄存器的32位低位半(
      %k0
      中的
      k
      修饰符)隐式转换为64位)


      令人惊讶的是,GCC也没有拒绝这一点;可能是由于
      开关(8)
      中的不可访问的
      大小写
      ,GCC将其作为死代码删除。如果您查看GCC的asm输出,它可能不包含该指令。

      请注意,
      clang
      在内联asm语句上使用其内置汇编程序。GCC总是使用Binutils中的外部
      作为
      ,只是在
      asm()
      语句上进行文本替换;GAS与clang的内置汇编程序不同,有时也没有clang的内置汇编程序那么挑剔。@PeterCordes:感谢您的澄清。请注意,
      clang
      在内联asm语句中使用其内置汇编程序。GCC总是使用Binutils中的外部
      作为
      ,只是在
      asm()
      语句上进行文本替换;GAS与clang的内置汇编程序不同,有时也不那么挑剔。@PeterCordes:谢谢你的澄清。
      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.