繁体   English   中英

在GCC中使用内联汇编从32位IMUL返回64位结果

[英]Returning a 64-bit result from a 32-bit IMUL with inline assembly in GCC

我试图从以下本质上获得结果...

Inputs EAX, EDX
IMUL EDX
Return EAX:EDX as full 64-bit result

我正在从https://gitorious.org/voxlap/voxlap/source/d467829d05294545ebb4cc088440421b57c7f38f:include/ksnippits.h#L281看这个示例

static inline long mulshr16 (long a, long d)
{
#if defined(__GNUC__) && defined(__i386__) && !defined(NOASM)
__asm__ __volatile__
(
"imul %[d]\n"
"shrd $16, %%edx, %[a]\n"
: [a] "+a" (a)
: [d] "r" (d)
: "edx"
);
return a;
#else // C Default
return (long)(((int64_t)a * (int64_t)d) >> 16);
#endif
}

我只是想保留驻留在EAX:EDX中的完整64位结果,而不是移位的结果,但是我不确定如何使用内联汇编器将其传递回GCC。

试试看,但要仔细测试:

#include <stdio.h>

static inline long long mul64 (long a, long d)
{
  long long rtn;
  __asm__ __volatile__("imull %[d]\n" : 
                       [rtn] "=A" (rtn) : [a] "a" (a), [d] "rm" (d) );
  return rtn;
}

int main(void) 
{
  printf("%lld should be -1524157875019052100.", mul64(-1234567890, 1234567890));
  return 0;
}

就像其他人所说的那样,以下定义产生几乎相同的代码:

static inline long long mul64 (long a, long d)
{
  return (long long)a * d;
}

除了编译器会折叠常量并在可能的情况下使用移位而不是乘法指令之外。 即在许多情况下它将生成更快的代码。

因此,我认为您imull某些原因总是希望发出不imull指令。 这是经历内联汇编之苦的唯一明确原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM