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.