if the following code results in something bigger than 2^128 will it produce a carry (out)?
mov rdx, -1 //rdx = 0xff...f
mov rax, -1 //rax = 0xff...f
mov rbx, -1 //rbx = 0xff...f
mul rbx //result will be bigger than 128 bits therefore will be pushed out of rdx
jc end
...
end: ret
So my question boils down to how the carry flag behaves when using the combined registers rax:rdx for mul
operations. Will jc
look automatically soley at the rdx register or also trigger when the result is bigger than rax?
CodePudding user response:
Refer Intel's Manual please... https://www.felixcloutier.com/x86/mul#flags-affected
MUL clears the CF if the upper half of the result (RDX, EDX, DX, or AH) is zero, else it's set.
mul
has two inputs of the same width. Only the output is double-width.
CF is not used to measure overflow of the whole thing, as two 64 bit multiplicands cannot result into a 129 bit result, so an overflow in that sense is not possible.
CF actually indicates overflow of the low half. Original 8086 didn't have non-widening multiply (imul ecx, esi
), so you had to use mul
or imul
even if you didn't care about the high-half result. Knowing that the result still fit in one register was potentially useful, especially in a 16-bit world where values wider than the widest available register were more common than on x86-64.