VS2019中switch反汇编Debug版(自学总结)

  • Post author:
  • Post category:其他


switch反汇编自学过程中的总结:

例子: 随便写一个3个case的switch,查看汇编。

void function()
{
	int i = 0;
	switch (i)
	{
	case 1:
		printf("1");
		break;
	case 2:
		printf("2");
		break;
	case 3:
		printf("3");
		break;
	default:
		printf("error");
		break;
	}
}

看得出与if的反汇编并无差别,并且挨个判断。所以如果没有3个以上的case条件可不必要使用switch。


修改一下例子:

void function()
{
	int i = 0;
	switch (i)
	{
	case 1:
		printf("1");
		break;
	case 2:
		printf("2");
		break;
	case 3:
		printf("3");
		break;
	case 4:
		printf("4");
		break;
	case 5:
		printf("5");
		break;
	default:
		printf("error");
		break;
	}
}

反汇编代码:

其中0x6A1918 是编译器为switch生成的表的第一个地址。


这就是生成的大表。

ecx为判断的变量的值。

sub ecx,1


减1中的‘1’是和


cmp dword ptr [ebp-0D0h],4


中的‘4’加起来为case中最大的判断值。


jmp  dword ptr [edx*4+6D1918h]


为跳转地址计算公式,dex*4中dex可以理解为偏移量(switch表)。即可直接跳转到目的地址(下一条指令)。



以上为一般(规范)switch。


!!!!!以下是不连续,乱序,差量过大的情况:

void function()
{
	int i = 102;
	switch (i)
	{
	case 102:
		printf("102");
		break;
	case 1:
		printf("1");
		break;
	case 2:
		printf("2");
		break;
	case 3:
		printf("3");
		break;
	case 4:
		printf("4");
		break;
	case 101:
		printf("101");
		break;
	case 104:
		printf("104");
		break;
	default:
		printf("error");
		break;
	}
}


当差距过大此编译器为再生成一个表上右图来计算(

movzx eax,byte ptr [edx+68195Ch]

)eax的值

生成了104字节的表。再通过eax的值得到偏移后的跳转地址。


总结:

switch适合于小量连续的判断条件。(生成的表不会浪费空间)



版权声明:本文为Sanshul原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。