簡體   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