用 goto + if 模拟 循环

本文通过使用goto和if模拟三种类型的循环(for、do-while、while),对比分析了它们的效率。通过对汇编代码的转换,得出结论:在相同的条件下,do-while循环效率最高。

循环的效率分析用 goto + if 模拟 循环(for, do-while, while)如果模拟费劲(if + goto 的次数统计多),说明效率低.

备注: for循环的++--是在循环体的上面是低地址不能在循环体内更改循环条件.

思路

先用C语言将循环写出来,将汇编代码复制出来备用,将CMP换成if, 将JMP换成goto, 将 JMP的地址换成标号.
这样就可以直接直接将汇编代码按照汇编代码的含义用C代码重写. 就完成了用if + goto 模拟循环的任务

源码

/// @file 2015_1026\exam_1_3\main.c
/// @brief
/**
* 循环的效率分析, 用 goto + if 模拟 循环(for, do-while, while)如果模拟费劲(if + goto 的次数统计多),说明效率低.
备注: for循环的++或--是在循环体的上面, 是低地址. 不能在循环体内更改循环条件.
*/

#include <stdlib.h>
#include <stdio.h>

void testLoop(); ///< test real loop(for, do-while, while)
void MyLoop_for(); ///< use gogo + if make our loop(for)
void MyLoop_do_while(); ///< use gogo + if make our loop(do-while)
void MyLoop_while(); ///< use gogo + if make our loop(while)

int main(int argc, char** argv)
{
	// testLoop();
	MyLoop_for();
	MyLoop_do_while();
	MyLoop_while();

	getchar();
	return 0;
}

void testLoop()
{
	int iIndex = 0;
	const int iCntMax = 3;

	printf("===for===\n");
	for (iIndex = 0; iIndex < iCntMax; iIndex++)
	{
		printf("iIndex = %d\n", iIndex);
	}

	printf("===do-while===\n");
	iIndex = 0;
	do 
	{
		printf("iIndex = %d\n", iIndex);
	} while (iIndex++ < iCntMax);

	printf("===while===\n");
	iIndex = 0;
	while (iIndex++ < iCntMax)
	{
		printf("iIndex = %d\n", iIndex);
	}
}

void MyLoop_for()
{
	/**
	29:       for (iIndex = 0; iIndex < iCntMax; iIndex++)
	00401103   mov         dword ptr [ebp-4],0
	0040110A   jmp         testLoop+45h (00401115)
	0040110C   mov         eax,dword ptr [ebp-4]
	0040110F   add         eax,1
	00401112   mov         dword ptr [ebp-4],eax
	00401115   mov         ecx,dword ptr [ebp-4]
	00401118   cmp         ecx,dword ptr [ebp-8]
	0040111B   jge         testLoop+60h (00401130)
	30:       {
	31:           printf("iIndex = %d\n", iIndex);
	0040111D   mov         edx,dword ptr [ebp-4]
	00401120   push        edx
	00401121   push        offset string "iIndex = %d\n" (00423040)
	00401126   call        printf (00401590)
	0040112B   add         esp,8
	32:       }
	0040112E   jmp         testLoop+3Ch (0040110c)
	*/

	/// 模拟 for 循环
	/// 参考for循环的汇编代码
	int iIndex = 0;
	const int iCntMax = 3;
	
	printf("===sim for===\n");
	iIndex = 0;
	goto label_for_compare;

label_for_next:
	iIndex++;

label_for_compare:
	if (iIndex > (iCntMax - 1))
		goto label_for_end;

	printf("iIndex = %d\n", iIndex);
	goto label_for_next;

label_for_end:
	;
}

void MyLoop_do_while()
{
/**
37:       iIndex = 0;
00401103   mov         dword ptr [ebp-4],0
38:       do
39:       {
40:           printf("iIndex = %d\n", iIndex);
0040110A   mov         eax,dword ptr [ebp-4]
0040110D   push        eax
0040110E   push        offset string "iIndex = %d\n" (0042302c)
00401113   call        printf (004015c0)
00401118   add         esp,8
41:       } while (iIndex++ < iCntMax);
0040111B   mov         ecx,dword ptr [ebp-4]
0040111E   mov         edx,dword ptr [ebp-8]
00401121   mov         eax,dword ptr [ebp-4]
00401124   add         eax,1
00401127   mov         dword ptr [ebp-4],eax
0040112A   cmp         ecx,edx
0040112C   jl          testLoop+3Ah (0040110a)
*/

	int iIndex = 0;
	const int iCntMax = 3;

	printf("===sim do-while===\n");
label_do_while:
	printf("iIndex = %d\n", iIndex);
	if (iIndex++ < iCntMax)
		goto label_do_while;
}

void MyLoop_while()
{
	/**
	46:       iIndex = 0;
	00401113   mov         dword ptr [ebp-4],0
	47:       while (iIndex++ < iCntMax)
	0040111A   mov         eax,dword ptr [ebp-4]
	0040111D   mov         ecx,dword ptr [ebp-8]
	00401120   mov         edx,dword ptr [ebp-4]
	00401123   add         edx,1
	00401126   mov         dword ptr [ebp-4],edx
	00401129   cmp         eax,ecx
	0040112B   jge         testLoop+60h (00401140)
	48:       {
	49:           printf("iIndex = %d\n", iIndex);
	0040112D   mov         eax,dword ptr [ebp-4]
	00401130   push        eax
	00401131   push        offset string "iIndex = %d\n" (0042301c)
	00401136   call        printf (00401630)
	0040113B   add         esp,8
	50:       }
	0040113E   jmp         testLoop+3Ah (0040111a)
	51:   }
	*/

	int iIndex = 0;
	const int iCntMax = 3;

	iIndex = 0;
	printf("===sim while===\n");
label_while_begin:
	if (iIndex++ > (iCntMax - 1))
		goto label_while_end;

	printf("iIndex = %d\n", iIndex);
	goto label_while_begin;

label_while_end:
	;
}


运行效果


分析

vsIDE中,在运行到循环入口处,切换到反汇编窗口将循环的反汇编代码拷贝出来。将CMP改成if, JMP改成goto, 即可用goto + if 完全模拟3种循环(for, do-while, while)

在相同条件下(循环条件相同,循环体代码相同), 经过比较可知 效率最高 => do-while => while => for => 效率最低.

 

效率的定义汇编代码行数最少.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值