前面一节,我讲到了两个对象交换的四种方法,今天,通过调试,来比较下这四种方法的汇编代码,测试环境为vc6.0

方法1:

temp = a;
mov eax, dword ptr[ebp + 8] //ptr[ebp + 8]为a的地址
mov ecx, dword ptr[eax]     //在ecx中暂存a中的内容
mov dword ptr[ebp-4], ecx   //ebp-4为c的地址,将a的值赋值给temp

a = b;
mov edx, dword ptr[ebp+8]   //取a的地址
mov eax, dword ptr[ebp+0Ch] //取b的地址, ptr[ebp+0Ch]为b的地址
mov ecx, dword ptr[eax]     //在ecx中存放b的值
mov dword ptr[edx], ecx     //将b的值赋值给a

b = temp;
mov edx, dword ptr[ebp+0ch] //取b的地址
mov eax, dword ptr[ebp-4]   //读temp中的值
mov dword ptr[edx],eax      //把temp的值赋值给b


方法2:
a = a^b;
mov eax, dword ptr[ebp+8]      //取a的地址
mov ecx, dword ptr[ebp+0ch]    //取b的地址
mov edx, dword ptr[eax]        //将a的值存放在寄存器中
xor edx, dword ptr[ecx]        //进行异或操作
mov eax, dword ptr[ebp+8]      //取a的地址
mov dword ptr[eax], edx        //把数据写回到a中

b = a^b;
mov ecx, dword ptr[ebp+8]      //取a的地址
mov edx, dword ptr[ebp+0ch]    //取b的地址
mov eax, dword ptr[ecx]        //将a的值存放在寄存器中
xor eax, dword ptr[edx]        //进行异或操作
mov ecx, dword ptr[ebp+0ch]    //取b的地址
mov dword ptr[ecx], eax        //把数据写回到b中

a = a^b;
mov edx, dword ptr[ebp+8]      //取a的地址
mov eax, dword ptr[ebp+0ch]    //取b的地址
mov ecx, dword ptr[edx]        //将a的值存放在寄存器中
xor ecx, dword ptr[eax]        //进行异或操作
mov edx, dword ptr[ebp+8]      //取a的地址
mov dword ptr[ebp+8], ecx      //把数据写回到a中



方法3:
a = a + b;
mov eax, dword ptr[ebp+8]       //取a的地址
mov ecx, dword ptr[eax]         //读a的值到寄存器中
mov edx, dword ptr[ebp+0ch]     //取b的地址
add ecx, dword ptr[edx]         //进行加操作
mov eax, dword ptr[ebp+8]       //取a的地址
mov dword ptr[eax], ecx         //把数据写回到a中

b = a - b;
mov ecx, dword ptr[ebp+8]       //取a的地址
mov edx, dword ptr[ebp+0ch]     //取b的地址
mov eax, dword ptr[ecx]         //读a的值到寄存器中
sub eax, dword ptr[edx]         //进行减操作
mov ecx, dword ptr[ebp+0ch]     //取b的地址
mov dword ptr[ecx], eax         //把数据写回到b中

a = a - b;
mov edx, dword ptr[ebp+8]       //取a的地址
mov eax, dword ptr[ebp+0ch]     //取b的地址
mov ecx, dword ptr[edx]         //读a的值到寄存器中
sub ecx, dword ptr[eax]         //进行减操作
mov edx, dword ptr[ebp+8]       //取a的地址
mov dword ptr[ebp+8], ecx       //把数据写回到a中


方法4:
a = a * b;
mov eax, dword ptr[ebp+8]       //取a的地址
mov ecx, dword ptr[ebp+0ch]     //取b的地址
mov edx, dword ptr[eax]         //读a的值到寄存器中
imul edx, dword ptr[ecx]        //进行乘操作
mov eax, dword ptr[ebp+8]       //取a的地址
mov dword ptr[eax], ecx         //把数据写回到a中

b = a / b;
mov ecx, dword ptr[ebp+8]       //取a的地址
mov esi, dword ptr[ebp+0ch]     //取b的地址
mov eax, dword ptr[ecx]         //读a的值到寄存器中
cdq                             //先把edx的每一位置为eax的最高位,再把edx扩展为eax的高位
idiv eax, dword ptr[esi]        //进行除法操作
mov edx, dword ptr[ebp+0ch]     //取b的地址
mov dword ptr[edx], eax         //把数据写回到b中

a = a / b;
mov eax, dword ptr[ebp+8]       //取a的地址
mov ecx, dword ptr[ebp+0ch]     //取b的地址
mov eax, dword ptr[eax]         //读a的值到寄存器中
cdq                             //先把edx的每一位置为eax的最高位,再把edx扩展为eax的高位
idiv eax, dword ptr[ecx]        //进行除法操作
mov edx, dword ptr[ebp+8]       //取a的地址
mov dword ptr[edx], eax         //把数据写回到a中


仅从汇编代码的行数来看,使用乘除法的代码量最大,异或和加减法的代码量次之,使用中间变量的方法的代码量最小,因此使用中间变量的方法效果不一定差。