clang __asm__ with labels in case statment, gets error: invalid operand for instruction
clang __asm__ with labels in case statment, gets error: invalid operand for instruction
我正在尝试在 C
源代码(检测)中添加 labels
;汇编经验少,编译器 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.
我正在使用:
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__
。
- 向语句添加标签使其可访问。
GCC
忽略它。
Clang
不理会。
movb
是 8 位操作数大小,%rax
是 64 位,因为您使用了 unsigned long long
。只需使用 mov
进行与输出变量宽度相同的加载,或使用 movzbl %%gs:%1, %k0
零扩展至 64 位。 (使用 movzbl
显式转换为 32 位,通过写入 64 位寄存器的 32 位低半部分(%k0
中的 k
修饰符)隐式转换为 64 位)
惊讶的 GCC 也没有拒绝它;也许 GCC 将它作为死代码删除,因为 switch(8)
中无法访问 case
。如果您查看 GCC 的 asm 输出,它可能不包含该指令。
我正在尝试在 C
源代码(检测)中添加 labels
;汇编经验少,编译器 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.
我正在使用:
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__
。 - 向语句添加标签使其可访问。
GCC
忽略它。Clang
不理会。
movb
是 8 位操作数大小,%rax
是 64 位,因为您使用了 unsigned long long
。只需使用 mov
进行与输出变量宽度相同的加载,或使用 movzbl %%gs:%1, %k0
零扩展至 64 位。 (使用 movzbl
显式转换为 32 位,通过写入 64 位寄存器的 32 位低半部分(%k0
中的 k
修饰符)隐式转换为 64 位)
惊讶的 GCC 也没有拒绝它;也许 GCC 将它作为死代码删除,因为 switch(8)
中无法访问 case
。如果您查看 GCC 的 asm 输出,它可能不包含该指令。