For a short homework in CS Architecture, we were moved to the next build of IA-32 in C. I translated it correctly (as far as I know), but the code does not work. It seems that something is especially useful. My professor usually gives us problems that end up doing something: our last assignment like this was a little pop_count. Looking at the C code below does this do anything useful? Maybe some kind of algorithm?
Below is the code (I added comments to each line of ASM).
// The following variables x, y, z are located at (%ebp) +8, +12, +16 respectively // x, y, and z, are scanned from the terminal and passed into the function movl 12(%ebp), %edx // moves long y to register %edx subl 16(%ebp), %edx // subtracts longs: y = y - z movl %edx, %eax // moves long y to register %eax sall $31, %eax // left shift all bits in long y by 31 places sarl $31, %eax // arithmetic right shift long y by 31 places imull 8(%ebp), %edx // multiply longs: unshifted y = y * x xorl %edx, %eax // XOR operation: shifted y = shifted y ^ unshifted y // The returned value is stored in register %eax
The effective offset is to subtract z from y, and then fill each bit with the least significant bit to form either zero or MAX_UINT. This is XOR'd with the product (y - z) * x and returns.
My translation in C:
return (((y - z) << 31) >> 31) ^ ((y - z) * x); // In more words: int f; y -= z; f = y << 31; // These two lines populate all bits with the lsb f = f >> 31; // Effectively, if yz is odd: f is ~0; else f is 0 y *= x; return y ^ f; // Or, using people logic: y -= z; if (y % 2 == 0) return y * x; return -(y * x) - 1; // If the yz is odd, the result will be: -1 * ((y - z) * x) - 1 // If the yz is even, the result will be: (y - z) * x
For clarification, this is not part of the purpose of HW; I completed the task by translating the code, but I am interested to know why he gave us this code to begin with.
c assembly x86 algorithm reverse-engineering
SeniorShizzle
source share