还是看的那篇算法大全的文章,见有个九九乘法表,想来应该是白痴的嵌套循环加IMUL等指令的东西,敲下代码。OD一反,却见不到我所料了IMUL,而只有那鹤立鸡群的 add ebx,edi。。。。。。。
程序源代码:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
void main()
{
int i,j,result;
printf("\n");
for(i=1;i<=10;i++)
{
for(j=1;j<=10;j++)
{
result=i*j;
printf("%d*%d=%-3d",i,j,result);
}
printf("\n");/*每一行后换行*/
}
printf("\n");
}
跳过废话看代码:
00401000 /$ 53 push ebx
00401001 |. 56 push esi
00401002 |. 57 push edi ; 寄存器保存
00401003 |. 68 3C704000 push 0040703C
00401008 |. E8 53000000 call 00401060 ; 输出换行符
0040100D |. 83C4 04 add esp, 4 ; 恢复堆栈
00401010 |. BF 01000000 mov edi, 1 ; for:i=1
00401015 |> BE 01000000 /mov esi, 1 ; for:j=1
0040101A |. 8BDF |mov ebx, edi
0040101C |> 53 |push ebx ; result
0040101D |. 56 |push esi ; j
0040101E |. 57 |push edi ; i
0040101F |. 68 30704000 |push 00407030 ; ASCII "%d*%d=%-3d"
00401024 |. E8 37000000 |call 00401060 ; 第一次必然输出1*1=1
00401029 |. 83C4 10 |add esp, 10 ; 恢复堆栈
0040102C |. 46 |inc esi ; j++
0040102D |. 03DF |add ebx, edi ; result=result+i(为什么会这样啊!!请看最下面分解)
0040102F |. 83FE 0A |cmp esi, 0A ; cmp j,10
00401032 |.^ 7E E8 |jle short 0040101C ; 不过10次循环则继续循环
00401034 |. 68 3C704000 |push 0040703C
00401039 |. E8 22000000 |call 00401060 ; 输出换行符
0040103E |. 83C4 04 |add esp, 4
00401041 |. 47 |inc edi ; i++
00401042 |. 83FF 0A |cmp edi, 0A
00401045 |.^ 7E CE \jle short 00401015 ; 10次i循环。。
00401047 |. 68 3C704000 push 0040703C
0040104C |. E8 0F000000 call 00401060 ; 换行符
00401051 |. 83C4 04 add esp, 4
00401054 |. 5F pop edi
00401055 |. 5E pop esi
00401056 |. 5B pop ebx
00401057 \. C3 retn
00401001 |. 56 push esi
00401002 |. 57 push edi ; 寄存器保存
00401003 |. 68 3C704000 push 0040703C
00401008 |. E8 53000000 call 00401060 ; 输出换行符
0040100D |. 83C4 04 add esp, 4 ; 恢复堆栈
00401010 |. BF 01000000 mov edi, 1 ; for:i=1
00401015 |> BE 01000000 /mov esi, 1 ; for:j=1
0040101A |. 8BDF |mov ebx, edi
0040101C |> 53 |push ebx ; result
0040101D |. 56 |push esi ; j
0040101E |. 57 |push edi ; i
0040101F |. 68 30704000 |push 00407030 ; ASCII "%d*%d=%-3d"
00401024 |. E8 37000000 |call 00401060 ; 第一次必然输出1*1=1
00401029 |. 83C4 10 |add esp, 10 ; 恢复堆栈
0040102C |. 46 |inc esi ; j++
0040102D |. 03DF |add ebx, edi ; result=result+i(为什么会这样啊!!请看最下面分解)
0040102F |. 83FE 0A |cmp esi, 0A ; cmp j,10
00401032 |.^ 7E E8 |jle short 0040101C ; 不过10次循环则继续循环
00401034 |. 68 3C704000 |push 0040703C
00401039 |. E8 22000000 |call 00401060 ; 输出换行符
0040103E |. 83C4 04 |add esp, 4
00401041 |. 47 |inc edi ; i++
00401042 |. 83FF 0A |cmp edi, 0A
00401045 |.^ 7E CE \jle short 00401015 ; 10次i循环。。
00401047 |. 68 3C704000 push 0040703C
0040104C |. E8 0F000000 call 00401060 ; 换行符
00401051 |. 83C4 04 add esp, 4
00401054 |. 5F pop edi
00401055 |. 5E pop esi
00401056 |. 5B pop ebx
00401057 \. C3 retn
上面的代码输出了九九乘法表,但是我们甚至没看到一个mul或imul!那是因为VC的优化效果!
以下是九九乘法表的第二行。
2*1=2
2*2=4
2*3=6
2*4=8
2*5=10
………
这里的1,2,3,4,5是等差数列2,4,6,8,10是等比数列,而被乘数恒为2
我们发现形如此式子的计算结果往往是上一条式子的运算结果加上被乘数。
这里的代码正是将ebx作为累加器把之前的结果保存起来,再不失时机地加上外循环的计数变量
而我们原以为能大显身手的j变量因为上面的数学规律的发现而只能充当循环结束的判断变量了!!
以下是九九乘法表的第二行。
2*1=2
2*2=4
2*3=6
2*4=8
2*5=10
………
这里的1,2,3,4,5是等差数列2,4,6,8,10是等比数列,而被乘数恒为2
我们发现形如此式子的计算结果往往是上一条式子的运算结果加上被乘数。
这里的代码正是将ebx作为累加器把之前的结果保存起来,再不失时机地加上外循环的计数变量
而我们原以为能大显身手的j变量因为上面的数学规律的发现而只能充当循环结束的判断变量了!!