1

I am trying to interpret the following IA32 assembler code and write a function in C that will have an equivalent effect.

Let's say that parameters a, b and c are stored at memory locations with offsets 8, 12 and 16 relative to the address in register %ebp, and that an appropriate function prototype in C would be equivFunction(int a, int b, int c);

movl 12(%ebp), %edx // store b into %edx
subl 16(%ebp), %edx // %edx = b - c
movl %edx, %eax     // store b - c into %eax
sall $31, %eax      // multiply (b-c) * 2^31
sarl $31, %eax      // divide ((b-c)*2^31)) / 2^31
imull 8(%ebp), %edx // multiply a * (b - c) into %edx
xorl %edx, %eax     // exclusive or? %edx or %eax ?  what is going on here?

First, did I interpret the assembly correctly? If so, how would I go about translating this into C?

4

2 回答 2

1

sall/组合具有将sarleax 的所有位设置为第零位的值的效果。首先,sal将第 0 位移动到第 31 位,使其成为符号位。然后sar将其移回,用其副本填充寄存器的其余部分。不要将其视为除法/乘法 - 将其视为按位移位,“s”实际上代表。

因此,如果 bc 为奇数,则 eax 为 0xffffffff (-1),如果为偶数,则为 0。因此,该imull命令将 a 的负数或零放入 edx。然后, finalxor要么反转 的所有位a(这就是xorone 所做的),要么将零值保留为。

这整个片段有一种做作的气氛。这是作业吗?

于 2013-11-06T19:32:21.697 回答
1

移位直接操作符号位,而不是乘法/除法,所以代码大致是

int eqivFunction(int a, int b, int c) {
    int t1 = b - c;
    unsigned t2 = t1 < 0 ? ~0U : 0;
    return (a * t1) ^ t2;
}

交替:

int eqivFunction(int a, int b, int c) {
    int t1 = b - c;
    int t2 = a * t1;
    if (t1 < 0) t2 = -t2 - 1;
    return t2;
}

当然,C 代码在整数溢出时具有未定义的行为,而汇编代码是明确定义的,因此 C 代码可能不会在所有情况下都做同样的事情(特别是如果你在不同的架构上编译它)

于 2013-11-06T19:34:17.093 回答