The documentation for imul states that:
SF is updated according to the most significant bit of the operand-size-truncated result in the destination.
For a 64-bit operation, then, my understanding is that SF = (a * b) >> 63
, or more simply if a
and b
are signed, SF = a * b < 0
.
However, I'm getting an unexpected result multiplying two large numbers:
mov rax, 0x9090909090909095
mov rdx, 0x4040404040404043
imul rax, rdx
The result of 0x9090909090909095 * 0x4040404040404043
is 0xefcba7835f3b16ff
. It has the sign bit set, however the SF flag is cleared after the imul
instruction. What's going on?
This was cross-posted to the Intel forums some time ago.
Other sources say that SF is undefined after imul
. This most likely means that the result of SF is well-defined on newer processors, but older ones don't offer the feature. My computer being 5 years old, I probably fall with the second category.
EDIT: using Archive.org's Wayback Machine, I found that the documentation changed from stating that SF is undefined to SF is defined in the September 2014 revision. The previous revision, June 2014, still says that SF is undefined. This is documented in the accompanying Documentation Changes document, though the rationale for the change is not.
EDIT 2 My CPU is an i7 M 620. I had access to an even older Core2Duo P7550 and was able to confirm that imul
doesn't set SF
on it either.
EDIT 3 Starting from the September 2016 edition, IMUL
says that SF is undefined, so this resolves the issue.