解释这个汇编代码

时间:2013-11-06 19:21:39

标签: c assembly x86

我正在尝试解释以下IA32汇编程序代码并在C中编写一个具有同等效果的函数。

假设参数abc存储在相对于偏移81216的内存位置寄存器%ebp中的地址,C中的适当函数原型为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?

首先,我是否正确地解释了装配?如果是这样,我将如何将其翻译成C?

2 个答案:

答案 0 :(得分:1)

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

因此,如果b-c为奇数,则eax为0xffffffff(-1),如果为偶数则为0。因此imull命令将edx放入a的负数或零。然后,最后的xor或者反转a的所有位(这是xor与其中的一位)或者保留零值。

整个片段都有一种人造气息。这是家庭作业吗?

答案 1 :(得分: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代码在所有情况下可能不会做同样的事情(特别是如果你在不同的架构上编译它)< / p>