8位内联汇编大小不匹配旋转

我想写使用内联汇编用C离开操作的旋转,像这样:8位内联汇编大小不匹配旋转

byte rotate_left(byte a) { 

__asm__("rol %0, $1": "=a" (a) : "a" (a));

return a;

}

(凡字节通过typedef unsigned char型)。

这就提出了一个错误

/tmp/ccKYcEHR.s:363: Error: operand size mismatch for `rol'.

有什么问题吗?

回答:

AT & T语法使用与Intel语法相反的顺序。旋转次数必须是第一次,而不是最后一次:rol $1, %0


而且,你不需要和不应该使用内联汇编本:https://gcc.gnu.org/wiki/DontUseInlineAsm

如Best practices for circular shift (rotate) operations in C++描述,GNU C有狭窄的旋转内部函数,因为旋转,惯用语法识别代码失败优化掉旋转计数的and。即使对于8位和16位,x86移位/旋转掩码的计数也为count & 31,但旋转仍然环绕。尽管如此,换班确实很重要。

无论如何,gcc有一个内置函数用于缩小旋转以避免任何开销。在x86intrin.h中有一个__rolb包装,但MSVC使用其自己的__rotr8等等intrin.h。无论如何,clang不支持__builtinx86intrin.h旋转包装,但gcc和ICC都支持。

#include <stdint.h> 

uint8_t rotate_left_byte_by1(uint8_t a) {

return __builtin_ia32_rolqi(a, 1); // qi = quarter-integer

}

我用uint8_tstdint.h像正常人代替限定byte类型。

这并不能编译铿锵,但it compiles as you'd hope with gcc7.2:

rotate_left_byte_by1: 

movl %edi, %eax

rolb %al

ret

这使您尽可能高效编译为您的内联汇编都做不到的功能,但它可以完全优化掉了编译时常量,并且编译器知道它是如何工作的以及它做了什么并且可以相应地进行优化。

以上是 8位内联汇编大小不匹配旋转 的全部内容, 来源链接: utcz.com/qa/267366.html

回到顶部