环境:Debian 9.5 - gcc 6.3.0
当我尝试使用多个 InputOperands
时,我无法使嵌入式汇编函数正常工作。
我有以下代码工作(基本 rol
函数,1 InputOperand
,预定义 rol
操作数):
#include <stdio.h>
#include <stdlib.h>
void asm_rol(int32_t* p_rolled)
{
__asm__ volatile
(
".intel_syntax noprefix;"
"rol %0, 1;"
:"=a"(*p_rolled)
:"a"(*p_rolled)
:"cc"
);
}
int main(int argc, char** argv)
{
int32_t test = 0x1;
asm_rol(&test);
printf("0x%08x\n", test);
return 0;
}
这将打印 0x00000002
,并且是 rol 0x1, 1
的正确结果。
现在我不明白为什么下面的代码不能编译。我认为我对 InputOperands
的使用不好:
#include <stdio.h>
#include <stdlib.h>
void asm_rol(int32_t* p_rolled, int16_t i)
{
__asm__ volatile
(
".intel_syntax noprefix;"
"rol %0, %1;"
:"=a"(*p_rolled)
:"a"(*p_rolled), "b"(i)
:"cc"
);
}
int main(int argc, char** argv)
{
int32_t test = 0x1;
asm_rol(&test, 1);
printf("0x%08x\n", test);
return 0;
}
gcc 返回错误:
resolve.c: Assembler messages:
resolve.c:6: Error: operand type mismatch for `rol'
我尝试使用 int8_t
和 int32_t
来表示 i
,它没有改变任何东西。
我必须说,在这个环境中,我对 C 中的嵌入式 asm 还很陌生,我只在 Windows 上使用 Visual Studio 完成了一些基本的内联汇编。
最佳答案
正如 Michael Petch 在评论中所说,
the only register that is allowed for a shifting instruction that controls the number of bits to shift is CL
他还提供了以下解决方案:
void asm_rol(int32_t* p_rolled, int8_t i) { __asm__ volatile ( ".intel_syntax noprefix;" "rol %0, %1;" :"+a"(*p_rolled) :"cI"(i) :"cc" ); }
The c says to use the CL register (assuming you change the type of variable i to int8_t instead of int16_t. . The Capital-Eye (I) says the constraint can also be an immediate value between 0 and 32.
正如 Michael Petch 和 Peter Cordes 在评论中指出的那样,我的代码无法正常工作,因为我使用 %1
作为 rol
操作数,但正确的变量是%2
。我犯了这个错误,因为我认为 %#
只引用了 InputOperands
。
Michael Petch 和 Peter Cordes 还提供了一些不错的文档:
(...) machine constraints can be found here: gcc.gnu.org/onlinedocs/gcc/… under the i386 info
There's no reason to use inline asm for rotates. Best practices for circular shift (rotate) operations in C++
When debugging inline asm, you should look at the compiler-generated asm to see what it substituted into the template. e.g. godbolt.org is handy: How to remove "noise" from GCC/clang assembly output?. You can even do stuff like nop # %0 %1 %2 to just see what the compiler picked for all the operands, whether you reference them in the template or not. See also stackoverflow.com/tags/inline-assembly/info for more guides and examples.
关于c - 汇编错误: "operand type mismatch for ` rol'"with multiple input operands,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53137123/