Your goal is to analyse the following compiler-generated assembly language code and to understand how it works.
... mov edx, Var1 mov ecx, Var2 mov eax, edx imul ecx mov edx, eax imul edx, eax mov Var3, ecx ...
You must retrieve the proper C/C++ code or pseudo code of this commented code. Your solution has to contain either a full commented C/C++ code or a detailed pseudo code describing the function of the above snippet.
ok this is a rough pseudocode of whats going on here.
int var1 = 6;
int var2 = 4;
int res = var1*var2;
res*=res;
return 0;
First var1 and var2 are mulyplied to eachother, then the result is multiplied to itself (also can use power instruction)
asm explanation.
the set up of mul is made here, because the one operancd imul uses the eax as the multiplier thery place edx into eax (mov eax, edx) then perform the multiplication
imul ecx, the result is placed into the eax register which is moved to edx, then that is multiplied by itself. just to note though the imul returns its result in the EDX:EAX register because it is 32bit signed values. but then we proceed to overwirte edx with result and multiply it to itself.. and ecx is saved to var3 :) i couldnt test or verify my pseudo or C code cause i used notepawd no compiler here :/ im bored at work :D
thanks for your explanation. I couldn’t figure out why it was overriding var1 value with its own, var1 after the multiplication, just didn’t make sense. Until you happened to mention that the result from the imul was being saved into edx:eax.
imul ecx is equivalent to:
EDX:EAX <- ecx * eax
which is:
EDX:EAX <- Var1 * Var2
Var1 and Var2 are presumably 32 bits each. 32bit * 32bit could result in a 64 bit number.
So EDX could be storing the upper 32bits of the result of the multiplication.
The next instruction:
mov edx,eax
moves the lower 32 bits of the product into EDX, thus overwriting the upper 32 bits of the product which EDX was storing.
correct?
>snip>
imul edx, eax
>snip>
the imul instruction takes only one operand not two..wtf
imul edx, eax
is a variant of imul that generates a 32 (vice 64) bit result into the destination register (in this case edx). Here you have effectively:
edx *= eax;
with no extension to 64 bits. Any overflow is simply lost. The single register version uses edx:eax as the implied destination register
(Var1 * Var2) ^ 2;
Var3 = Var2;
Could this be the solution?
good word in noting that imul ecx actually left ecx alone since it puts the results in edx:eax
you can also deduct that there is some casts in there since edx (the high part of the long long results is always discarted)
tmp = (long)(Var1 * Var2) * (long)(Var1 * Var2);
Var3 = Var2;
you can also assume that tmp will be used later (if optimizations are on)