arm64彙編篇 12Switch底層執行原理

2021-08-20 13:14:57 字數 2040 閱讀 5525

1、假設switch語句的分支比較少的時候(例如3,少於4的時候沒有意義)沒有必要使用此結構,相當於if。

2、各個分支常量的差值較大的時候,編譯器會在效率還是記憶體進行取捨,這個時候編譯器還是會編譯成類似於if,else的結構。

三個及以下case

1.建立工程在main函式頁面寫下如下**:

void funa(int a)

}

2.debug -> debug overflow -> always show disassembly 調成編譯斷點模式在方法處打斷點,真機執行檢視彙編**。

3.上圖基本流程如下(省略系統正常操作):

1.將引數a-1判斷a和1是否相等

2.相等則執行case**

3.不相等則將引數 a - 2再判斷 a 和 2是否相等

4.根據case遞增判斷知道default 結束

注:這和if else判斷相似乙個乙個比較,是最基本的方法。

四個case

1.輸入以下**

void funa(int a)

}

2.編譯真機執行獲得如下結果:

3.如上**析:

1.先將引數減一和減四(4位case的數量)。

2.先判斷是否為default選項(上面減四就是為了判斷是否為default的情況)。

3.在實體地址部分建立記憶體表並且將case按順序放進記憶體表中

4.獲取記憶體位址,然後根據引數減一後偏移2個單位,查詢case在表中的具體位址準確找到對應的位址記憶體並且將值賦給暫存器。

5.根據獲得的位址跳轉指定的case直接找到目標執行。

4.神奇的記憶體計算,下面附上記憶體計算過程的,因為重新執行程式左邊的記憶體位址會有差異但是pc執行**是一樣的:

彙編指令的用法見

1.首先獲取物理記憶體位址為0x1040ce8a8

2.根據引數傳的是3,然後減一得2(10)偏移兩個單位即1000為8位得到bc ff ff ff**記憶體位址是從右往左讀的**

3.將獲得的實體地址0x1040ce8a8加上計算得出的偏移位址後就等到了跳轉執行位址(即在記憶體**中確定具體記憶體位置)。

4.直接跳轉執行。

注:計算方法為將實體地址0x1040ce8a8 + 0xffffffffbc = 0x1040ce8a8 - 0x44(取反加1 補碼 詳見補碼) = 0x1040ce864計算結果跟上圖列印結果完全一致是不是很神奇?分部差異大的例子

1.輸入以下**

void funa(int a)

}

2.編譯真機執行獲得如下結果:

3.解析:

當case的判斷條件跳躍性太大,編譯器就會變為if判斷一樣採用一一比較的方式進行判斷效率是不高的。

所以在寫switch語句的時候盡量要將其判斷的case連續起來這樣即減少執行時間又節省系統記憶體

這邊簡單介紹下,差異小的部分編譯器會根據系統記憶體和時間之間取捨,比如4個case差值在8之間會建八個元素的表,剛才4個記憶體位,現在就是8個記憶體位,case以外的間隔預設為default。具體的時間空間問題是編譯器決定的。

Arm64彙編 BFXIL指令

下屬專案 測試用例數量 問題背景無0 解決方法無1 總結無0復現一套加密演算法時,遇到了bfxil指令。ida中顯示情況如下 bfxil w9,w16,2 2 ida使用fn f5操作得到偽 如下 v4 v4 v8 0xfc 2 3 其中v4就是w9,v8 0xfc 這個整體就是w16,定義如下 u...

arm64彙編篇 014 指標的運算

指標的寬度 1.寫入下面 真機執行 void func 2.得出結果為8即指標在64位中的寬度為8個位元組。指標的運算void func 2.解析 1.a為指標 2.將100強轉 int 指標賦值給a 3.a自增 4.列印a 得出結果為104。由此得出 指標的運算結果由器所指向的資料型別寬度決定 資...

arm64入棧出棧 棧 ARM64

棧 棧 是一種具有特殊的訪問方式的儲存空間 後進先出,last in out firt,lifo sp和fp暫存器 sp暫存器在任意時刻會儲存我們棧頂的位址.fp暫存器也稱為x29暫存器屬於通用暫存器,但是在某些時刻我們利用它儲存棧底的位址 注意 arm64開始,取消32位的 ldm,stm,pus...