有符号数溢出:
void BreakFor() { for (int i = 1; i > 0; i++) { printf("%d ", i); } }
上面的程序并不是死循环,当有符号数增加到最大整数后,继续加一会进位修改符号位,从而成为负数。
自增、自减
98: int nVarOne = argc; 012665EE 8B 45 08 mov eax,dword ptr [argc] 012665F1 89 45 F8 mov dword ptr [nVarOne],eax 99: int nVarTwo = argc; 012665F4 8B 45 08 mov eax,dword ptr [argc] 012665F7 89 45 EC mov dword ptr [nVarTwo],eax 100: nVarTwo = 5 + (nVarOne++); 012665FA 8B 45 F8 mov eax,dword ptr [nVarOne] 012665FD 83 C0 05 add eax,5 01266600 89 45 EC mov dword ptr [nVarTwo],eax 01266603 8B 4D F8 mov ecx,dword ptr [nVarOne] 01266606 83 C1 01 add ecx,1 //后缀自增,在语句结束后加一
01266609 89 4D F8 mov dword ptr [nVarOne],ecx 101: nVarTwo = 5 + (++nVarOne); 0126660C 8B 45 F8 mov eax,dword ptr [nVarOne] 0126660F 83 C0 01 add eax,1 //前缀自增,先自增 01266612 89 45 F8 mov dword ptr [nVarOne],eax 01266615 8B 4D F8 mov ecx,dword ptr [nVarOne] 01266618 83 C1 05 add ecx,5 0126661B 89 4D EC mov dword ptr [nVarTwo],ecx 102: 103: nVarOne = 5 + (nVarTwo--); 0126661E 8B 45 EC mov eax,dword ptr [nVarTwo] 01266621 83 C0 05 add eax,5 01266624 89 45 F8 mov dword ptr [nVarOne],eax 01266627 8B 4D EC mov ecx,dword ptr [nVarTwo] 0126662A 83 E9 01 sub ecx,1 0126662D 89 4D EC mov dword ptr [nVarTwo],ecx 104: nVarOne = 5 + (--nVarTwo); 01266630 8B 45 EC mov eax,dword ptr [nVarTwo] 01266633 83 E8 01 sub eax,1 01266636 89 45 EC mov dword ptr [nVarTwo],eax 01266639 8B 4D EC mov ecx,dword ptr [nVarTwo] 0126663C 83 C1 05 add ecx,5 0126663F 89 4D F8 mov dword ptr [nVarOne],ecx 105: }
表达式截断:
124: (nNumber == 0) || (nNumber += Accumulation(nNumber - 1)); 0126650E 83 7D 08 00 cmp dword ptr [nNumber],0 01266512 74 15 je Accumulation+39h (01266529h) //前面为零,截断表达式,直接跳转 01266514 8B 45 08 mov eax,dword ptr [nNumber] 01266517 83 E8 01 sub eax,1 0126651A 50 push eax 0126651B E8 8B B4 FE FF call Accumulation (012519ABh) // 01266520 83 C4 04 add esp,4 01266523 03 45 08 add eax,dword ptr [nNumber] 01266526 89 45 08 mov dword ptr [nNumber],eax 125: return nNumber; 01266529 8B 45 08 mov eax,dword ptr [nNumber] 126: }
条件表达式:
- 方案1:表达式1为简单比较,而表达式2和表达3两者的差值等于1;
return argc == 5 ? 5 : 6;
00E44BB6 | 8B7D 08 | mov edi,dword ptr ss:[ebp+0x8] | 00E44BB9 | 33C0 | xor eax,eax | 00E44BBB | 83FF 05 | cmp edi,0x5 | 00E44BBE | 0F95C0 | setne al |//差值为一,用到setne,取得ZF值后,取反,再放到AL中,即不等时置AL为1 00E44BC1 | 83C0 05 | add eax,0x5 |
- 方案2:表达式1为简单比较,而表达式2和表达式3两者的差值大于1;
return argc == 5 ? 4 : 10;
00E44BCF | BE 0A000000 | mov esi,0xA | 00E44BD4 | 83FF 05 | cmp edi,0x5 | 00E44BD7 | 8BC6 | mov eax,esi | 00E44BD9 | BB 04000000 | mov ebx,0x4 | 00E44BDE | 0F44C3 | cmove eax,ebx |//相等的时候用ebx-->4代替eax-->10
vc6.0下
- 方案3:表达式2和表达式3两者的差值大于1;
return argc >= 8 ? 4 : 10;
00E44BEC | 83FF 08 | cmp edi,0x8 | 00E44BEF | 8BC6 | mov eax,esi | esi-->1000E44BF1 | 0F4DC3 | cmovge eax,ebx |//大于等于时,用ebx-->4代替eax-->10
在vc6.0下
- 方案4:表达式2和表达式3有一个为变量,于是无优化。
位运算:
141: unsigned int nVar = argc; 0126668E 8B 45 08 mov eax,dword ptr [argc] 01266691 89 45 F8 mov dword ptr [nVar],eax 142: nVar <<= 3; 01266694 8B 45 F8 mov eax,dword ptr [nVar] 01266697 C1 E0 03 shl eax,3 //无符号数<< 使用shl 逻辑左移 0126669A 89 45 F8 mov dword ptr [nVar],eax 143: nVar >>= 5; 0126669D 8B 45 F8 mov eax,dword ptr [nVar] 012666A0 C1 E8 05 shr eax,5 //无符号数>> 使用shr 逻辑右移 012666A3 89 45 F8 mov dword ptr [nVar],eax 144: 145: argc = argc << 3; 012666A6 8B 45 08 mov eax,dword ptr [argc] 144: 145: argc = argc << 3; 012666A9 C1 E0 03 shl eax,3 012666AC 89 45 08 mov dword ptr [argc],eax 146: argc = argc >> 5; 012666AF 8B 45 08 mov eax,dword ptr [argc] 012666B2 C1 F8 05 sar eax,5 //有符号数>> 使用sar 算术右移 012666B5 89 45 08 mov dword ptr [argc],eax 147: argc = argc | 0xFFFF0000; 012666B8 8B 45 08 mov eax,dword ptr [argc] 012666BB 0D 00 00 FF FF or eax,0FFFF0000h 012666C0 89 45 08 mov dword ptr [argc],eax 148: argc = argc & 0x0000FFFF; 012666C3 8B 45 08 mov eax,dword ptr [argc] 012666C6 25 FF FF 00 00 and eax,0FFFFh 012666CB 89 45 08 mov dword ptr [argc],eax 149: argc = argc ^ 0xFFFF0000; 012666CE 8B 45 08 mov eax,dword ptr [argc] 012666D1 35 00 00 FF FF xor eax,0FFFF0000h 012666D6 89 45 08 mov dword ptr [argc],eax 150: argc = ~argc; 012666D9 8B 45 08 mov eax,dword ptr [argc] 012666DC F7 D0 not eax 012666DE 89 45 08 mov dword ptr [argc],eax 151: 152: return argc; 012666E1 8B 45 08 mov eax,dword ptr [argc]