Hello and welcome back.
In this lesson, we are going to study IMUL.
IMUL is for signed multiplication.
It differs from MUL.
In the previous lesson, we used MUL for unsigned multiplication.
There are two main forms of the IMUL instruction.
The first is IMUL, followed by one operand.
In this case, we have to move the first operand into the - register.
Then in this instruction, we specify the second operand.
Maybe - or -.
Then the second form is IMUL operand 1, operand 2. In this
in this form,
both operands are storing the values.
Maybe operand one is -.
Operand two could be -, -.
And then when we perform the instruction, it will take the value in operand two, multiply with operand
one and store the result in operand one.
The one operand form.
IMUL operand.
This is similar to MUL.
This form multiplies the - register by the operand, and the result is stored in the - - pair.
The most significant bits of the result are stored in -, and the least significant 64 bits are
stored in -.
Two operand form.
IMUL operand 1, operand 2.
This form multiplies the second operand by the first operand and stores the result in the first operand
register.
In this case, - is not inherently used unless it is explicitly specified as the destination operand,
so there is a basic difference here.
The IMUL operand one, two form, the result is stored only in the - register.
- is not used, so the size of the register is half of the size that is used in the IMUL
the first form.
When dealing with the IMUL instruction.
Signed multiplication.
Whether or not the - register is used to store part of the result depends on the specific form
of the IMUL instruction being used.
So if we use this form, then it will store the result in - -.
But if we use this form, it will only store the result in the first operand, which is only a single
register in the two operand form.
What happens if the result of the IMUL is too large to store in the first operand?
So if that is the case in the two operand form, if the result of the multiplication is too large
to fit in the 64-bit destination register, the overflow will not be stored in another register.
Instead, the result will be truncated to fit within the 64-bit destination register.
This means that only the least significant 64 bits of the result are kept, and the most significant
bits which cannot fit are discarded.
Unlike the one operand form of IMUL, which stores the overflow into the - register, the two operand
form does not inherently provide any direct indication of overflow within the registers.
To detect an overflow condition from a two operand IMUL, you will need to analyze the flags in the
flags register.
The carry flag and the overflow flag are set
if the result is too large to be represented in the destination register, indicating an overflow condition.
These flags need to be checked after the operation
if the preservation of the full result or the detection of an overflow is important to the logic of
the program.
So in summary, for IMUL in 64-bit mode, - is used to store the most significant 64 bits of the
results only in the one operand form of the instruction, where the operation affects the - - register
pair.
In the two operand form, - is not used to store the result unless it is explicitly specified as the
destination operand, and we need to check the - and - flags to know whether an overflow has occurred.
So now let's take a look at the example inside the
x64dbg.
I've loaded my template 2X file.
So now we are going to move a number inside the register -.
So we move
-
five.
We are now going to move - negative three.
Note that I am entering here a decimal number.
So when it enters into the x64dbg, it will convert it into hex.
So this is five.
This is negative three.
And you can confirm that with your calculator.
If you enter negative three, select decimal, three,
and then negative, you will see the negative three is indeed all Fs followed by D.
So now let's go and do the first operand.
Single operand form.
The single operand form is IMUL -.
So when you step over this.
So we run to our breakpoint, step over.
It moves five to our -, and then it moves negative three to -.
Now it's going to multiply - to - and store the result in - -.
Step over and you see the result is in - -.
The result is this result.
So if we take our calculator and then we retry, we enter five, select decimal first, five, and then
multiply with negative three.
We will get this result.
All Fs followed by one.
So if we see here, we get all Fs
or Fs followed by one.
So this is correct.
So the result is -15, which is represented by all Fs followed by one.
Note that this is a signed multiplication.
That's why you see F. The most significant bit is a one, indicating that it is a negative number.
Now we're going to try the second form of IMUL which takes two operands.
So this time we are going to move -.
We are going to move five into -.
And then we are going to move.
We are going to move, uh, negative three into -.
So as you can see now, five is in -.
And then negative three is in -.
Now we are going to do a multiplication in the second form of IMUL which takes two operands.
So -, -.
-, so the result will be stored in -.
So we step over.
It is move five to our -.
It has moved five to -, and it has moved negative three to -.
So now we are going to multiply the two, and the result should be stored in -.
So this is how we can use the assembly inside x64dbg to implement IMUL.
That's all for this video.
Thank you for watching.