这段翻译好的汇编代码还有什么更大的意义吗?

Is there any larger significance to this piece of translated assembly code?

对于 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 , %eax                       // left shift all bits in long y by 31 places 
   sarl , %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

有效的结论是我们从 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

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

我的猜测是您的教授试图说明如何使用 bit-shifting/masking 操作来避免分支。如果你天真地翻译

y -= z;
if (y % 2 == 0) return y * x;
return -(y * x) - 1;

转换为机器代码,您可以为条件语句使用分支指令。分支会显着降低您的代码速度,尤其是当它们处于紧密循环中时*。汇编代码和您前面的 C 代码具有使用条件 y - z 是否为偶数的效果,但仅使用算术指令。

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