ARM64匯編學(xué)習(xí)筆記四(IF僧叉、循環(huán)和 Switch)

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

  1. 假設(shè) switch 內(nèi)分支比較多的時(shí)候漠魏,在編譯的時(shí)候會(huì)生成一個(gè)表(跳轉(zhuǎn)表每個(gè)地址四個(gè)字節(jié));
  2. 假設(shè) switch 內(nèi)分支比較少的時(shí)候(例如3妄均,少于4的時(shí)候沒(méi)有意義)柱锹,就沒(méi)有必要使用此結(jié)構(gòu)哪自,相當(dāng)于if...else語(yǔ)句的結(jié)構(gòu);
  3. 假設(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í)行效率更高。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末韵卤,一起剝皮案震驚了整個(gè)濱河市骗污,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沈条,老刑警劉巖需忿,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡贴谎,警方通過(guò)查閱死者的電腦和手機(jī)汞扎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)擅这,“玉大人,你說(shuō)我怎么就攤上這事景鼠≈亵幔” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵铛漓,是天一觀的道長(zhǎng)溯香。 經(jīng)常有香客問(wèn)我,道長(zhǎng)浓恶,這世上最難降的妖魔是什么玫坛? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮包晰,結(jié)果婚禮上湿镀,老公的妹妹穿的比我還像新娘。我一直安慰自己伐憾,他們只是感情好勉痴,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著树肃,像睡著了一般蒸矛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胸嘴,一...
    開(kāi)封第一講書(shū)人閱讀 49,185評(píng)論 1 284
  • 那天雏掠,我揣著相機(jī)與錄音,去河邊找鬼劣像。 笑死乡话,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的驾讲。 我是一名探鬼主播蚊伞,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼吮铭!你這毒婦竟也來(lái)了时迫?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤谓晌,失蹤者是張志新(化名)和其女友劉穎掠拳,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體纸肉,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡溺欧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年喊熟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姐刁。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡芥牌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出聂使,到底是詐尸還是另有隱情壁拉,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布柏靶,位于F島的核電站弃理,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏屎蜓。R本人自食惡果不足惜痘昌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望炬转。 院中可真熱鬧辆苔,春花似錦、人聲如沸返吻。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)测僵。三九已至街佑,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捍靠,已是汗流浹背沐旨。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留榨婆,地道東北人磁携。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哮独,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容