#include <iostream>
int main()
{int a = 1;switch (a){case 1:{std::cout << a;}case 2:{std::cout << a;}case 3:{std::cout << a;}default:break;}
}
以下是汇编代码(3个case以内的 与IF的汇编逻辑一致)
0088201D mov eax,dword ptr [a] //将参数赋值给 eax
00882020 mov dword ptr [ebp-0D0h],eax //eax存储在栈的某个位置
00882026 cmp dword ptr [ebp-0D0h],1 //将参数与1做比较
0088202D je __$EncStackInitStart+47h (0882043h) //是否跳转
0088202F cmp dword ptr [ebp-0D0h],2 //将参数与2比较
00882036 je __$EncStackInitStart+61h (088205Dh) //是否跳转
00882038 cmp dword ptr [ebp-0D0h],3 //将参数与3比较
0088203F je __$EncStackInitStart+7Bh (0882077h) //是否跳转
00882041 jmp __$EncStackInitStart+95h (0882091h) //都不符合直接跳转到出栈逻辑00882043 mov esi,esp
00882045 mov eax,dword ptr [a]
00882048 push eax
00882049 mov ecx,dword ptr [__imp_std::cout (088D0C8h)]
0088204F call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (088D0D0h)]
00882055 cmp esi,esp
00882057 call __RTC_CheckEsp (0881294h)
0088205C nop 0088205D mov esi,esp
0088205F mov eax,dword ptr [a]
00882062 push eax
00882063 mov ecx,dword ptr [__imp_std::cout (088D0C8h)]
00882069 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (088D0D0h)]
0088206F cmp esi,esp
00882071 call __RTC_CheckEsp (0881294h)
00882076 nop 00882077 mov esi,esp
00882079 mov eax,dword ptr [a]
0088207C push eax
0088207D mov ecx,dword ptr [__imp_std::cout (088D0C8h)]
00882083 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (088D0D0h)]
00882089 cmp esi,esp
0088208B call __RTC_CheckEsp (0881294h)
00882090 nop //出栈逻辑
00882091 xor eax,eax
00882093 pop edi
00882094 pop esi
00882095 pop ebx
00882096 add esp,0D0h
0088209C cmp ebp,esp
0088209E call __RTC_CheckEsp (0881294h)
008820A3 mov esp,ebp
008820A5 pop ebp
008820A6 ret
四个case
#include <iostream>
int main()
{int a = 2;switch (a){case 1:{std::cout << a;}case 2:{std::cout << a;}case 3:{std::cout << a;}case 4:{std::cout << a;}default:break;}
}
以下是汇编代码
0011201D mov eax,dword ptr [a] //将参数赋值给eax
00112020 mov dword ptr [ebp-0D0h],eax //eax存储在栈的某个位置
00112026 mov ecx,dword ptr [ebp-0D0h] //再将值赋值给ecx
0011202C sub ecx,1 //ecx-1=1
0011202F mov dword ptr [ebp-0D0h],ecx
00112035 cmp dword ptr [ebp-0D0h],3 //减3
0011203C ja $LN7+1Ah (01120B3h) //跳转到结束位置
0011203E mov edx,dword ptr [ebp-0D0h]
00112044 jmp dword ptr [edx*4+1120CCh] //跳转到对应的case方法 0011204B mov esi,esp
0011204D mov eax,dword ptr [a]
00112050 push eax
00112051 mov ecx,dword ptr [__imp_std::cout (011D0C8h)]
00112057 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (011D0D0h)]
0011205D cmp esi,esp
0011205F call __RTC_CheckEsp (0111294h)
00112064 nop 00112065 mov esi,esp
00112067 mov eax,dword ptr [a]
0011206A push eax
0011206B mov ecx,dword ptr [__imp_std::cout (011D0C8h)]
00112071 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (011D0D0h)]
00112077 cmp esi,esp
00112079 call __RTC_CheckEsp (0111294h)
0011207E nop 0011207F mov esi,esp
00112081 mov eax,dword ptr [a]
00112084 push eax
00112085 mov ecx,dword ptr [__imp_std::cout (011D0C8h)]
0011208B call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (011D0D0h)]
00112091 cmp esi,esp
00112093 call __RTC_CheckEsp (0111294h)
00112098 nop 00112099 mov esi,esp
0011209B mov eax,dword ptr [a]
0011209E push eax
0011209F mov ecx,dword ptr [__imp_std::cout (011D0C8h)]
001120A5 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (011D0D0h)]
001120AB cmp esi,esp
001120AD call __RTC_CheckEsp (0111294h)
001120B2 nop 001120B3 xor eax,eax
001120B5 pop edi
001120B6 pop esi
001120B7 pop ebx
001120B8 add esp,0D0h
001120BE cmp ebp,esp
001120C0 call __RTC_CheckEsp (0111294h)
001120C5 mov esp,ebp
001120C7 pop ebp
001120C8 ret
结论:
case大于3的时候 编译器会把每一个case的方法地址分别存到栈的一个位置中,判断的时候直接去跳转对应的地址
case小于3的时候 与IF的汇编流程一致
一脸懵逼,后期补补汇编的知识