cmp(Compare)比較指令
cmp:把一個(gè)寄存器的內(nèi)容和另一個(gè)寄存器的內(nèi)容或立即數(shù)進(jìn)行比較奕枝。但不存儲(chǔ)結(jié)果,只是正確的更改標(biāo)志瓶堕。
一般 cmp 做完判斷后會(huì)進(jìn)行跳轉(zhuǎn)隘道,后面通常會(huì)跟上B指令。
- BL 標(biāo)號(hào):跳轉(zhuǎn)到標(biāo)號(hào)處執(zhí)行
- B.LT 標(biāo)號(hào):比較結(jié)果是小于(less than)郎笆,執(zhí)行標(biāo)號(hào)谭梗,否則不跳轉(zhuǎn);
- B.LE 標(biāo)號(hào):比較結(jié)果是小于等于(less than or equal to)宛蚓,執(zhí)行標(biāo)號(hào)激捏,否則不跳轉(zhuǎn);
- B.GT 標(biāo)號(hào):比較結(jié)果是大于(greater than)凄吏,執(zhí)行標(biāo)號(hào)远舅,否則不跳轉(zhuǎn);
- B.GE 標(biāo)號(hào):比較結(jié)果是大于等于(greater than or equal to)痕钢,執(zhí)行標(biāo)號(hào)图柏,否則不跳轉(zhuǎn);
- B.EQ 標(biāo)號(hào):比較結(jié)果是等于任连,執(zhí)行標(biāo)號(hào)蚤吹,否則不跳轉(zhuǎn);
- B.HI 標(biāo)號(hào):比較結(jié)果是無(wú)符號(hào)大于课梳,執(zhí)行標(biāo)號(hào)距辆,否則不跳轉(zhuǎn);
if...else的識(shí)別
- 源碼
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
void func(int a,int b){
int temp = 0;
if (a >= b) {
temp = a;
}else{
temp = b;
}
}
int main(int argc, char * argv[]) {
func(10, 20);
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
- func 函數(shù)的匯編代碼
__text:0000000100006798 ; =============== S U B R O U T I N E =======================================
__text:0000000100006798
__text:0000000100006798
__text:0000000100006798 EXPORT _func
__text:0000000100006798 _func ; CODE XREF: _main+28↓p
__text:0000000100006798
__text:0000000100006798 var_C = -0xC
__text:0000000100006798 var_8 = -8
__text:0000000100006798 var_4 = -4
__text:0000000100006798
__text:0000000100006798 SUB SP, SP, #0x10
__text:000000010000679C STR W0, [SP,#0x10+var_4]
__text:00000001000067A0 STR W1, [SP,#0x10+var_8]
__text:00000001000067A4 STR WZR, [SP,#0x10+var_C]
__text:00000001000067A8 LDR W0, [SP,#0x10+var_4]
__text:00000001000067AC LDR W1, [SP,#0x10+var_8]
__text:00000001000067B0 CMP W0, W1
__text:00000001000067B4 B.LT loc_1000067C4
__text:00000001000067B8 LDR W8, [SP,#0x10+var_4]
__text:00000001000067BC STR W8, [SP,#0x10+var_C]
__text:00000001000067C0 B loc_1000067CC
__text:00000001000067C4 ; ---------------------------------------------------------------------------
__text:00000001000067C4
__text:00000001000067C4 loc_1000067C4 ; CODE XREF: _func+1C↑j
__text:00000001000067C4 LDR W8, [SP,#0x10+var_8]
__text:00000001000067C8 STR W8, [SP,#0x10+var_C]
__text:00000001000067CC
__text:00000001000067CC loc_1000067CC ; CODE XREF: _func+28↑j
__text:00000001000067CC ADD SP, SP, #0x10
__text:00000001000067D0 RET
__text:00000001000067D0 ; End of function _func
匯編代碼分析
// 1. 判斷條件
__text:00000001000067B0 CMP W0, W1
__text:00000001000067B4 B.LT loc_1000067C4
/*
結(jié)合這兩句代碼表示暮刃,判斷(CMP) w0 和 w1 的比較結(jié)果是否小于跨算。
如果是小于,則執(zhí)行標(biāo)號(hào)(loc_1000067C4)以下的代碼椭懊,否則不跳轉(zhuǎn)繼續(xù)執(zhí)行下 面的代碼诸蚕。
*/
// 2. 不滿(mǎn)足條件不跳轉(zhuǎn)繼續(xù)執(zhí)行
__text:00000001000067B8 LDR W8, [SP,#0x10+var_4]
__text:00000001000067BC STR W8, [SP,#0x10+var_C]
// 3. 滿(mǎn)足條件跳轉(zhuǎn)標(biāo)號(hào)執(zhí)行
__text:00000001000067C4 loc_1000067C4 ; CODE XREF: _func+1C↑j
__text:00000001000067C4 LDR W8, [SP,#0x10+var_8]
__text:00000001000067C8 STR W8, [SP,#0x10+var_C]
do…while 循環(huán)的識(shí)別
- 源碼
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
void func() {
int nSum = 0;
int i = 0;
do {
i++;
nSum = nSum + i;
} while (i < 100);
}
int main(int argc, char * argv[]) {
func();
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
- func 函數(shù)的匯編代碼
__text:00000001000067AC ; =============== S U B R O U T I N E =======================================
__text:00000001000067AC
__text:00000001000067AC
__text:00000001000067AC EXPORT _func
__text:00000001000067AC _func ; CODE XREF: _main+18↓p
__text:00000001000067AC
__text:00000001000067AC var_8 = -8
__text:00000001000067AC var_4 = -4
__text:00000001000067AC
__text:00000001000067AC SUB SP, SP, #0x10
__text:00000001000067B0 STR WZR, [SP,#0x10+var_4]
__text:00000001000067B4 STR WZR, [SP,#0x10+var_8]
__text:00000001000067B8
__text:00000001000067B8 loc_1000067B8 ; CODE XREF: _func+30↓j
__text:00000001000067B8 LDR W8, [SP,#0x10+var_8]
__text:00000001000067BC ADD W8, W8, #1
__text:00000001000067C0 STR W8, [SP,#0x10+var_8]
__text:00000001000067C4 LDR W8, [SP,#0x10+var_4]
__text:00000001000067C8 LDR W9, [SP,#0x10+var_8]
__text:00000001000067CC ADD W8, W8, W9
__text:00000001000067D0 STR W8, [SP,#0x10+var_4]
__text:00000001000067D4 LDR W8, [SP,#0x10+var_8]
__text:00000001000067D8 CMP W8, #0x64
__text:00000001000067DC B.LT loc_1000067B8
__text:00000001000067E0 ADD SP, SP, #0x10
__text:00000001000067E4 RET
__text:00000001000067E4 ; End of function _func
匯編代碼分析
// 1. 判斷條件
__text:00000001000067D8 CMP W8, #0x64
__text:00000001000067DC B.LT loc_1000067B8
// 2. 滿(mǎn)足條件跳轉(zhuǎn)標(biāo)號(hào)執(zhí)行
__text:00000001000067B8 loc_1000067B8 ; CODE XREF: _func+30↓j
__text:00000001000067B8 LDR W8, [SP,#0x10+var_8]
__text:00000001000067BC ADD W8, W8, #1
__text:00000001000067C0 STR W8, [SP,#0x10+var_8]
__text:00000001000067C4 LDR W8, [SP,#0x10+var_4]
__text:00000001000067C8 LDR W9, [SP,#0x10+var_8]
__text:00000001000067CC ADD W8, W8, W9
__text:00000001000067D0 STR W8, [SP,#0x10+var_4]
__text:00000001000067D4 LDR W8, [SP,#0x10+var_8]
while 循環(huán)的識(shí)別
- 源碼
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
void func() {
int nSum = 0;
int i = 0;
while (i < 100){
i++;
nSum = nSum + i;
}
}
int main(int argc, char * argv[]) {
func();
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
- func 函數(shù)的匯編代碼
__text:00000001000067A8 ; =============== S U B R O U T I N E =======================================
__text:00000001000067A8
__text:00000001000067A8
__text:00000001000067A8 EXPORT _func
__text:00000001000067A8 _func ; CODE XREF: _main+18↓p
__text:00000001000067A8
__text:00000001000067A8 var_8 = -8
__text:00000001000067A8 var_4 = -4
__text:00000001000067A8
__text:00000001000067A8 SUB SP, SP, #0x10
__text:00000001000067AC STR WZR, [SP,#0x10+var_4]
__text:00000001000067B0 STR WZR, [SP,#0x10+var_8]
__text:00000001000067B4
__text:00000001000067B4 loc_1000067B4 ; CODE XREF: _func+34↓j
__text:00000001000067B4 LDR W8, [SP,#0x10+var_8]
__text:00000001000067B8 CMP W8, #0x64
__text:00000001000067BC B.GE loc_1000067E0
__text:00000001000067C0 LDR W8, [SP,#0x10+var_8]
__text:00000001000067C4 ADD W8, W8, #1
__text:00000001000067C8 STR W8, [SP,#0x10+var_8]
__text:00000001000067CC LDR W8, [SP,#0x10+var_4]
__text:00000001000067D0 LDR W9, [SP,#0x10+var_8]
__text:00000001000067D4 ADD W8, W8, W9
__text:00000001000067D8 STR W8, [SP,#0x10+var_4]
__text:00000001000067DC B loc_1000067B4
__text:00000001000067E0 ; ---------------------------------------------------------------------------
__text:00000001000067E0
__text:00000001000067E0 loc_1000067E0 ; CODE XREF: _func+14↑j
__text:00000001000067E0 ADD SP, SP, #0x10
__text:00000001000067E4 RET
__text:00000001000067E4 ; End of function _func
匯編代碼分析
// 1. 判斷條件是否滿(mǎn)足
__text:00000001000067B4 loc_1000067B4 ; CODE XREF: _func+34↓j
__text:00000001000067B4 LDR W8, [SP,#0x10+var_8]
__text:00000001000067B8 CMP W8, #0x64
__text:00000001000067BC B.GE loc_1000067E0
// 2.條件滿(mǎn)足則繼續(xù)執(zhí)行,執(zhí)行完最后一句代碼之后氧猬,又執(zhí)行第一步背犯,直到條件不滿(mǎn)足后再跳出循環(huán)
__text:00000001000067C0 LDR W8, [SP,#0x10+var_8]
__text:00000001000067C4 ADD W8, W8, #1
__text:00000001000067C8 STR W8, [SP,#0x10+var_8]
__text:00000001000067CC LDR W8, [SP,#0x10+var_4]
__text:00000001000067D0 LDR W9, [SP,#0x10+var_8]
__text:00000001000067D4 ADD W8, W8, W9
__text:00000001000067D8 STR W8, [SP,#0x10+var_4]
__text:00000001000067DC B loc_1000067B4
for 循環(huán)的識(shí)別
- 源碼
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
void func() {
for (int i = 0; i < 100; i++) {
printf("hello");
}
}
int main(int argc, char * argv[]) {
func();
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
- func 函數(shù)的匯編代碼
__text:000000010000678C ; =============== S U B R O U T I N E =======================================
__text:000000010000678C
__text:000000010000678C ; Attributes: bp-based frame
__text:000000010000678C
__text:000000010000678C EXPORT _func
__text:000000010000678C _func ; CODE XREF: _main+18↓p
__text:000000010000678C
__text:000000010000678C var_8 = -8
__text:000000010000678C var_4 = -4
__text:000000010000678C var_s0 = 0
__text:000000010000678C
__text:000000010000678C SUB SP, SP, #0x20
__text:0000000100006790 STP X29, X30, [SP,#0x10+var_s0]
__text:0000000100006794 ADD X29, SP, #0x10
__text:0000000100006798 STUR WZR, [X29,#var_4]
__text:000000010000679C
__text:000000010000679C loc_10000679C ; CODE XREF: _func+38↓j
__text:000000010000679C LDUR W8, [X29,#var_4]
__text:00000001000067A0 CMP W8, #0x64
__text:00000001000067A4 B.GE loc_1000067C8
__text:00000001000067A8 ADRP X0, #aHello@PAGE ; "hello"
__text:00000001000067AC ADD X0, X0, #aHello@PAGEOFF ; "hello"
__text:00000001000067B0 BL _printf
__text:00000001000067B4 STR W0, [SP,#0x10+var_8]
__text:00000001000067B8 LDUR W8, [X29,#var_4]
__text:00000001000067BC ADD W8, W8, #1
__text:00000001000067C0 STUR W8, [X29,#var_4]
__text:00000001000067C4 B loc_10000679C
__text:00000001000067C8 ; ---------------------------------------------------------------------------
__text:00000001000067C8
__text:00000001000067C8 loc_1000067C8 ; CODE XREF: _func+18↑j
__text:00000001000067C8 LDP X29, X30, [SP,#0x10+var_s0]
__text:00000001000067CC ADD SP, SP, #0x20
__text:00000001000067D0 RET
__text:00000001000067D0 ; End of function _func
匯編代碼分析
通過(guò)與 while 的匯編代碼對(duì)比,可以得知類(lèi)似于 while 循環(huán)語(yǔ)句盅抚。
Switch
- 假設(shè) switch 內(nèi)分支比較多的時(shí)候漠魏,在編譯的時(shí)候會(huì)生成一個(gè)表(跳轉(zhuǎn)表每個(gè)地址四個(gè)字節(jié));
- 假設(shè) switch 內(nèi)分支比較少的時(shí)候(例如3妄均,少于4的時(shí)候沒(méi)有意義)柱锹,就沒(méi)有必要使用此結(jié)構(gòu)哪自,相當(dāng)于if...else語(yǔ)句的結(jié)構(gòu);
- 假設(shè) switch 內(nèi)各個(gè)分支常量的差值較大的時(shí)候禁熏,編譯器會(huì)在效率還是內(nèi)存之間進(jìn)行取舍壤巷,如果效率優(yōu)先的情況下,這個(gè)時(shí)候編譯器還是會(huì)編譯成類(lèi)似于if..else的結(jié)構(gòu)瞧毙。
-
Switch 內(nèi)分支少于4的情況下:
源碼
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
void func(int a) {
switch (a) {
case 1:
printf("上路");
break;
case 2:
printf("中路");
break;
case 3:
printf("下路");
break;
default:
printf("隨機(jī)匹配");
break;
}
}
int main(int argc, char * argv[]) {
func(1);
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
匯編代碼
__text:0000000100006704 ; =============== S U B R O U T I N E =======================================
__text:0000000100006704
__text:0000000100006704 ; Attributes: bp-based frame
__text:0000000100006704
__text:0000000100006704 EXPORT _func
__text:0000000100006704 _func ; CODE XREF: _main+20↓p
__text:0000000100006704
__text:0000000100006704 var_24 = -0x24
__text:0000000100006704 var_20 = -0x20
__text:0000000100006704 var_1C = -0x1C
__text:0000000100006704 var_18 = -0x18
__text:0000000100006704 var_14 = -0x14
__text:0000000100006704 var_10 = -0x10
__text:0000000100006704 var_C = -0xC
__text:0000000100006704 var_8 = -8
__text:0000000100006704 var_4 = -4
__text:0000000100006704 var_s0 = 0
__text:0000000100006704
__text:0000000100006704 SUB SP, SP, #0x40
__text:0000000100006708 STP X29, X30, [SP,#0x30+var_s0]
__text:000000010000670C ADD X29, SP, #0x30
__text:0000000100006710 STUR W0, [X29,#var_4]
__text:0000000100006714 LDUR W0, [X29,#var_4]
__text:0000000100006718 MOV X8, X0
__text:000000010000671C SUBS W0, W0, #1
__text:0000000100006720 STUR W8, [X29,#var_8]
__text:0000000100006724 STUR W0, [X29,#var_C]
__text:0000000100006728 B.EQ loc_100006758
__text:000000010000672C B loc_100006730
__text:0000000100006730 ; ---------------------------------------------------------------------------
__text:0000000100006730
__text:0000000100006730 loc_100006730 ; CODE XREF: _func+28↑j
__text:0000000100006730 LDUR W8, [X29,#var_8]
__text:0000000100006734 SUBS W9, W8, #2
__text:0000000100006738 STUR W9, [X29,#var_10]
__text:000000010000673C B.EQ loc_10000676C
__text:0000000100006740 B loc_100006744
__text:0000000100006744 ; ---------------------------------------------------------------------------
__text:0000000100006744
__text:0000000100006744 loc_100006744 ; CODE XREF: _func+3C↑j
__text:0000000100006744 LDUR W8, [X29,#var_8]
__text:0000000100006748 SUBS W9, W8, #3
__text:000000010000674C STUR W9, [X29,#var_14]
__text:0000000100006750 B.EQ loc_100006780
__text:0000000100006754 B loc_100006794
__text:0000000100006758 ; ---------------------------------------------------------------------------
__text:0000000100006758
__text:0000000100006758 loc_100006758 ; CODE XREF: _func+24↑j
__text:0000000100006758 ADRP X0, #asc_100007F10@PAGE ; "上路"
__text:000000010000675C ADD X0, X0, #asc_100007F10@PAGEOFF ; "上路"
__text:0000000100006760 BL _printf
__text:0000000100006764 STR W0, [SP,#0x30+var_18]
__text:0000000100006768 B loc_1000067A4
__text:000000010000676C ; ---------------------------------------------------------------------------
__text:000000010000676C
__text:000000010000676C loc_10000676C ; CODE XREF: _func+38↑j
__text:000000010000676C ADRP X0, #asc_100007F17@PAGE ; "中路"
__text:0000000100006770 ADD X0, X0, #asc_100007F17@PAGEOFF ; "中路"
__text:0000000100006774 BL _printf
__text:0000000100006778 STR W0, [SP,#0x30+var_1C]
__text:000000010000677C B loc_1000067A4
__text:0000000100006780 ; ---------------------------------------------------------------------------
__text:0000000100006780
__text:0000000100006780 loc_100006780 ; CODE XREF: _func+4C↑j
__text:0000000100006780 ADRP X0, #asc_100007F1E@PAGE ; "下路"
__text:0000000100006784 ADD X0, X0, #asc_100007F1E@PAGEOFF ; "下路"
__text:0000000100006788 BL _printf
__text:000000010000678C STR W0, [SP,#0x30+var_20]
__text:0000000100006790 B loc_1000067A4
__text:0000000100006794 ; ---------------------------------------------------------------------------
__text:0000000100006794
__text:0000000100006794 loc_100006794 ; CODE XREF: _func+50↑j
__text:0000000100006794 ADRP X0, #asc_100007F25@PAGE ; "隨機(jī)匹配"
__text:0000000100006798 ADD X0, X0, #asc_100007F25@PAGEOFF ; "隨機(jī)匹配"
__text:000000010000679C BL _printf
__text:00000001000067A0 STR W0, [SP,#0x30+var_24]
__text:00000001000067A4
__text:00000001000067A4 loc_1000067A4 ; CODE XREF: _func+64↑j
__text:00000001000067A4 ; _func+78↑j ...
__text:00000001000067A4 LDP X29, X30, [SP,#0x30+var_s0]
__text:00000001000067A8 ADD SP, SP, #0x40
__text:00000001000067AC RET
__text:00000001000067AC ; End of function _func
匯編代碼分析
通過(guò)與 if...else 的匯編代碼對(duì)比胧华,可以得知類(lèi)似于 if...else 條件判斷語(yǔ)句。
-
Switch 內(nèi)分支大于等于4的情況下:
源碼
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
void func(int a) {
switch (a) {
case 1:
printf("上路");
break;
case 2:
printf("中路");
break;
case 3:
printf("下路");
break;
case 4:
printf("野區(qū)");
break;
default:
printf("隨機(jī)匹配");
break;
}
}
int main(int argc, char * argv[]) {
func(1);
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
匯編代碼
__text:00000001000066E8 ; =============== S U B R O U T I N E =======================================
__text:00000001000066E8
__text:00000001000066E8 ; Attributes: bp-based frame
__text:00000001000066E8
__text:00000001000066E8 EXPORT _func
__text:00000001000066E8 _func ; CODE XREF: _main+20↓p
__text:00000001000066E8
__text:00000001000066E8 var_28 = -0x28
__text:00000001000066E8 var_24 = -0x24
__text:00000001000066E8 var_20 = -0x20
__text:00000001000066E8 var_1C = -0x1C
__text:00000001000066E8 var_18 = -0x18
__text:00000001000066E8 var_14 = -0x14
__text:00000001000066E8 var_10 = -0x10
__text:00000001000066E8 var_4 = -4
__text:00000001000066E8 var_s0 = 0
__text:00000001000066E8
__text:00000001000066E8 SUB SP, SP, #0x40
__text:00000001000066EC STP X29, X30, [SP,#0x30+var_s0]
__text:00000001000066F0 ADD X29, SP, #0x30
__text:00000001000066F4 STUR W0, [X29,#var_4]
__text:00000001000066F8 LDUR W0, [X29,#var_4]
__text:00000001000066FC SUBS W0, W0, #1 ; switch 4 cases
__text:0000000100006700 MOV X8, X0
__text:0000000100006704 SUBS W0, W0, #3
__text:0000000100006708 STUR X8, [X29,#var_10]
__text:000000010000670C STUR W0, [X29,#var_14]
__text:0000000100006710 B.HI def_100006728 ; jumptable 0000000100006728 default case
__text:0000000100006714 ADRP X8, #jpt_100006728@PAGE
__text:0000000100006718 ADD X8, X8, #jpt_100006728@PAGEOFF
__text:000000010000671C LDUR X9, [X29,#var_10]
__text:0000000100006720 LDRSW X10, [X8,X9,LSL#2]
__text:0000000100006724 ADD X8, X10, X8
__text:0000000100006728 BR X8 ; switch jump
__text:000000010000672C ; ---------------------------------------------------------------------------
__text:000000010000672C
__text:000000010000672C loc_10000672C ; CODE XREF: _func+40↑j
__text:000000010000672C ; DATA XREF: __text:jpt_100006728↓o
__text:000000010000672C ADRP X0, #asc_100007F08@PAGE ; jumptable 0000000100006728 case 1
__text:0000000100006730 ADD X0, X0, #asc_100007F08@PAGEOFF ; "上路"
__text:0000000100006734 BL _printf
__text:0000000100006738 STR W0, [SP,#0x30+var_18]
__text:000000010000673C B loc_10000678C
__text:0000000100006740 ; ---------------------------------------------------------------------------
__text:0000000100006740
__text:0000000100006740 loc_100006740 ; CODE XREF: _func+40↑j
__text:0000000100006740 ; DATA XREF: __text:000000010000679C↓o
__text:0000000100006740 ADRP X0, #asc_100007F0F@PAGE ; jumptable 0000000100006728 case 2
__text:0000000100006744 ADD X0, X0, #asc_100007F0F@PAGEOFF ; "中路"
__text:0000000100006748 BL _printf
__text:000000010000674C STR W0, [SP,#0x30+var_1C]
__text:0000000100006750 B loc_10000678C
__text:0000000100006754 ; ---------------------------------------------------------------------------
__text:0000000100006754
__text:0000000100006754 loc_100006754 ; CODE XREF: _func+40↑j
__text:0000000100006754 ; DATA XREF: __text:00000001000067A0↓o
__text:0000000100006754 ADRP X0, #asc_100007F16@PAGE ; jumptable 0000000100006728 case 3
__text:0000000100006758 ADD X0, X0, #asc_100007F16@PAGEOFF ; "下路"
__text:000000010000675C BL _printf
__text:0000000100006760 STR W0, [SP,#0x30+var_20]
__text:0000000100006764 B loc_10000678C
__text:0000000100006768 ; ---------------------------------------------------------------------------
__text:0000000100006768
__text:0000000100006768 loc_100006768 ; CODE XREF: _func+40↑j
__text:0000000100006768 ; DATA XREF: __text:00000001000067A4↓o
__text:0000000100006768 ADRP X0, #asc_100007F1D@PAGE ; jumptable 0000000100006728 case 4
__text:000000010000676C ADD X0, X0, #asc_100007F1D@PAGEOFF ; "野區(qū)"
__text:0000000100006770 BL _printf
__text:0000000100006774 STR W0, [SP,#0x30+var_24]
__text:0000000100006778 B loc_10000678C
__text:000000010000677C ; ---------------------------------------------------------------------------
__text:000000010000677C
__text:000000010000677C def_100006728 ; CODE XREF: _func+28↑j
__text:000000010000677C ADRP X0, #asc_100007F24@PAGE ; jumptable 0000000100006728 default case
__text:0000000100006780 ADD X0, X0, #asc_100007F24@PAGEOFF ; "隨機(jī)匹配"
__text:0000000100006784 BL _printf
__text:0000000100006788 STR W0, [SP,#0x30+var_28]
__text:000000010000678C
__text:000000010000678C loc_10000678C ; CODE XREF: _func+54↑j
__text:000000010000678C ; _func+68↑j ...
__text:000000010000678C LDP X29, X30, [SP,#0x30+var_s0]
__text:0000000100006790 ADD SP, SP, #0x40
__text:0000000100006794 RET
__text:0000000100006794 ; End of function _func
匯編代碼分析
__text:00000001000066F4 STUR W0, [X29,#var_4]
__text:00000001000066F8 LDUR W0, [X29,#var_4]
__text:00000001000066FC SUBS W0, W0, #1 ; switch 4 cases
__text:0000000100006700 MOV X8, X0
__text:0000000100006704 SUBS W0, W0, #3
__text:0000000100006708 STUR X8, [X29,#var_10]
__text:000000010000670C STUR W0, [X29,#var_14]
__text:0000000100006710 B.HI def_100006728 ; jumptable 0000000100006728 default case
__text:0000000100006714 ADRP X8, #jpt_100006728@PAGE
__text:0000000100006718 ADD X8, X8, #jpt_100006728@PAGEOFF
__text:000000010000671C LDUR X9, [X29,#var_10]
__text:0000000100006720 LDRSW X10, [X8,X9,LSL#2]
__text:0000000100006724 ADD X8, X10, X8
__text:0000000100006728 BR X8 ; switch jump
//
1. switch 內(nèi)分支比較多的時(shí)候宙彪,在編譯的時(shí)候會(huì)生成一個(gè)表(跳轉(zhuǎn)表每個(gè)地址四個(gè)字節(jié))矩动;
2. 先判斷是否是 default 分支;// B.HI def_100006728
3. 取 X8的地址您访;
ADRP X8, #jpt_100006728@PAGE
ADD X8, X8, #jpt_100006728@PAGEOFF
// ADRP + ADD表示取值铅忿,常用于取常量和全局變量的值,但是這里取的是地址值灵汪。
LDUR X9, [X29,#var_10]
LDRSW X10, [X8,X9,LSL#2]
// LDRSW
// [X8,X9,LSL#2] 表示以 X8 為基地址檀训,X9的二進(jìn)制左移2位,再相加得到一個(gè)新的地址值享言。
// 例如:A表示(X8 為基地址)峻凫,B 表示(X9的二進(jìn)制左移2位)
// 那么 X10 = [A B];
ADD X8, X10, X8
// X8 = X10 和 X8的值相加
通過(guò)這一系列的運(yùn)行最后得到即將要跳轉(zhuǎn)地址值X8览露,這種方式的計(jì)算效率非常高荧琼,只需要一次算法,就能找到 X8 的地址差牛。
4. 跳轉(zhuǎn)到X8的地址命锄;
BR X8 ; switch jump
// 跳轉(zhuǎn)到 X8為標(biāo)號(hào)的地址執(zhí)行
-
Switch 內(nèi)各個(gè)分支常量的差值較大的情況下:
源碼
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
void func(int a) {
switch (a) {
case 10:
printf("上路");
break;
case 102:
printf("中路");
break;
case 700:
printf("下路");
break;
case 24:
printf("野區(qū)");
break;
default:
printf("隨機(jī)匹配");
break;
}
}
int main(int argc, char * argv[]) {
func(1);
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
匯編代碼
__text:00000001000066D4 ; =============== S U B R O U T I N E =======================================
__text:00000001000066D4
__text:00000001000066D4 ; Attributes: bp-based frame
__text:00000001000066D4
__text:00000001000066D4 EXPORT _func
__text:00000001000066D4 _func ; CODE XREF: _main+20↓p
__text:00000001000066D4
__text:00000001000066D4 var_2C = -0x2C
__text:00000001000066D4 var_28 = -0x28
__text:00000001000066D4 var_24 = -0x24
__text:00000001000066D4 var_20 = -0x20
__text:00000001000066D4 var_1C = -0x1C
__text:00000001000066D4 var_18 = -0x18
__text:00000001000066D4 var_14 = -0x14
__text:00000001000066D4 var_10 = -0x10
__text:00000001000066D4 var_C = -0xC
__text:00000001000066D4 var_8 = -8
__text:00000001000066D4 var_4 = -4
__text:00000001000066D4 var_s0 = 0
__text:00000001000066D4
__text:00000001000066D4 SUB SP, SP, #0x40
__text:00000001000066D8 STP X29, X30, [SP,#0x30+var_s0]
__text:00000001000066DC ADD X29, SP, #0x30
__text:00000001000066E0 STUR W0, [X29,#var_4]
__text:00000001000066E4 LDUR W0, [X29,#var_4]
__text:00000001000066E8 MOV X8, X0
__text:00000001000066EC SUBS W0, W0, #0xA
__text:00000001000066F0 STUR W8, [X29,#var_8]
__text:00000001000066F4 STUR W0, [X29,#var_C]
__text:00000001000066F8 B.EQ loc_10000673C
__text:00000001000066FC B loc_100006700
__text:0000000100006700 ; ---------------------------------------------------------------------------
__text:0000000100006700
__text:0000000100006700 loc_100006700 ; CODE XREF: _func+28↑j
__text:0000000100006700 LDUR W8, [X29,#var_8]
__text:0000000100006704 SUBS W9, W8, #0x18
__text:0000000100006708 STUR W9, [X29,#var_10]
__text:000000010000670C B.EQ loc_100006778
__text:0000000100006710 B loc_100006714
__text:0000000100006714 ; ---------------------------------------------------------------------------
__text:0000000100006714
__text:0000000100006714 loc_100006714 ; CODE XREF: _func+3C↑j
__text:0000000100006714 LDUR W8, [X29,#var_8]
__text:0000000100006718 SUBS W9, W8, #0x66
__text:000000010000671C STUR W9, [X29,#var_14]
__text:0000000100006720 B.EQ loc_100006750
__text:0000000100006724 B loc_100006728
__text:0000000100006728 ; ---------------------------------------------------------------------------
__text:0000000100006728
__text:0000000100006728 loc_100006728 ; CODE XREF: _func+50↑j
__text:0000000100006728 LDUR W8, [X29,#var_8]
__text:000000010000672C SUBS W9, W8, #0x2BC
__text:0000000100006730 STR W9, [SP,#0x30+var_18]
__text:0000000100006734 B.EQ loc_100006764
__text:0000000100006738 B loc_10000678C
__text:000000010000673C ; ---------------------------------------------------------------------------
__text:000000010000673C
__text:000000010000673C loc_10000673C ; CODE XREF: _func+24↑j
__text:000000010000673C ADRP X0, #asc_100007F08@PAGE ; "上路"
__text:0000000100006740 ADD X0, X0, #asc_100007F08@PAGEOFF ; "上路"
__text:0000000100006744 BL _printf
__text:0000000100006748 STR W0, [SP,#0x30+var_1C]
__text:000000010000674C B loc_10000679C
__text:0000000100006750 ; ---------------------------------------------------------------------------
__text:0000000100006750
__text:0000000100006750 loc_100006750 ; CODE XREF: _func+4C↑j
__text:0000000100006750 ADRP X0, #asc_100007F0F@PAGE ; "中路"
__text:0000000100006754 ADD X0, X0, #asc_100007F0F@PAGEOFF ; "中路"
__text:0000000100006758 BL _printf
__text:000000010000675C STR W0, [SP,#0x30+var_20]
__text:0000000100006760 B loc_10000679C
__text:0000000100006764 ; ---------------------------------------------------------------------------
__text:0000000100006764
__text:0000000100006764 loc_100006764 ; CODE XREF: _func+60↑j
__text:0000000100006764 ADRP X0, #asc_100007F16@PAGE ; "下路"
__text:0000000100006768 ADD X0, X0, #asc_100007F16@PAGEOFF ; "下路"
__text:000000010000676C BL _printf
__text:0000000100006770 STR W0, [SP,#0x30+var_24]
__text:0000000100006774 B loc_10000679C
__text:0000000100006778 ; ---------------------------------------------------------------------------
__text:0000000100006778
__text:0000000100006778 loc_100006778 ; CODE XREF: _func+38↑j
__text:0000000100006778 ADRP X0, #asc_100007F1D@PAGE ; "野區(qū)"
__text:000000010000677C ADD X0, X0, #asc_100007F1D@PAGEOFF ; "野區(qū)"
__text:0000000100006780 BL _printf
__text:0000000100006784 STR W0, [SP,#0x30+var_28]
__text:0000000100006788 B loc_10000679C
__text:000000010000678C ; ---------------------------------------------------------------------------
__text:000000010000678C
__text:000000010000678C loc_10000678C ; CODE XREF: _func+64↑j
__text:000000010000678C ADRP X0, #asc_100007F24@PAGE ; "隨機(jī)匹配"
__text:0000000100006790 ADD X0, X0, #asc_100007F24@PAGEOFF ; "隨機(jī)匹配"
__text:0000000100006794 BL _printf
__text:0000000100006798 STR W0, [SP,#0x30+var_2C]
__text:000000010000679C
__text:000000010000679C loc_10000679C ; CODE XREF: _func+78↑j
__text:000000010000679C ; _func+8C↑j ...
__text:000000010000679C LDP X29, X30, [SP,#0x30+var_s0]
__text:00000001000067A0 ADD SP, SP, #0x40
__text:00000001000067A4 RET
__text:00000001000067A4 ; End of function _func
匯編代碼分析
通過(guò)與 if...else 的匯編代碼對(duì)比,可以得知類(lèi)似于 if...else 條件判斷語(yǔ)句偏化。
小結(jié):
在使用 switch語(yǔ)句 和 if...else語(yǔ)句執(zhí)行效率高低的問(wèn)題脐恩,是可以通過(guò)匯編代碼得出結(jié)論:
當(dāng) switch 分支和 if...else的條件判斷小于4的時(shí)候,執(zhí)行效率是一樣的侦讨;
當(dāng) switch 分支和 if...else的條件判斷大于等于4的時(shí)候驶冒,switch 執(zhí)行效率更高。