这段翻译的汇编代码有什么更重要的意义吗?

Sen*_*zle 8 c algorithm x86 assembly reverse-engineering

对于CS体系结构中的简短家庭作业,我们将以下IA-32程序集转换为C.我已正确翻译它(据我所知),但代码似乎没有做任何特别有用的事情.我的教授通常会给我们这样的问题,最终会做一些事情:像我这样的最后一个任务就是pop_count.看下面的C代码,这个函数有用吗?有些算法可能吗?

代码如下所示(我已为每条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
Run Code Online (Sandbox Code Playgroud)

有效的结果是我们从y中减去z,然后用最低有效位填充每一位以形成零或MAX_UINT.这与(y - z)*x的乘积进行异或并返回.

我对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 y-z 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 y-z is odd, the result will be:    -1 * ((y - z) * x) - 1
// If the y-z is even, the result will be:              (y - z) * x
Run Code Online (Sandbox Code Playgroud)

为了澄清,这不是硬件分配的一部分; 我已经通过翻译代码完成了作业,但我很想知道他为什么开始给我们这个代码.

kor*_*rok 3

我的猜测是,您的教授试图说明如何使用位移/掩码操作来避免分支。如果你天真地翻译

y -= z;
if (y % 2 == 0) return y * x;
return -(y * x) - 1;
Run Code Online (Sandbox Code Playgroud)

到机器代码中,您可以使用条件分支指令。分支会极大地减慢您的代码速度,尤其是当它们位于紧密循环*内时。y - z汇编代码和前面的 C 代码具有使用条件判断是否为偶数的效果,但仅使用算术指令。

*如果您还不熟悉这个事实,这个答案有我最喜欢的插图之一。