現象基本可以描述為:對於乙個if分支結構,在**的時候單步跟蹤,發現在if和else中的語句塊都執行到了。貼個簡化的**:
if(10
==x)
else
當然,以上**只是示意,真正的應用中我們一般不會寫出這樣看似無意義的**。簡而言之,在單步跟蹤的過程中,發現y = 1;
和y = 2
都執行到了,這顯然不符合c語言的標準。
於是我開啟彙編檢視,發現在比較指令(cmp)後有一條指令:it eq
,其後緊跟兩個看似mov的指令,由於只學過x86彙編,對此也不太熟悉,就把兩條都當作mov的某個變體了。查閱資料後得知,類似it eq
的指令還有很多,例如ite
、itt
、itett
等,都屬於thumb指令集,是條件執行的指令。而跟在其後的mov也並非簡單的mov指令,而是moveq
和movne
,分別是「move (while) equal」和「move (while) not equal」的意思。而諸如此類的指令,在arm中都稱為「條件執行」的指令,只有當某種條件符合的時候(例如狀態暫存器的某位被置位),該指令才真正執行相應的操作,否則不做任何處理。
一般情況下,在if或else後面只跟了一兩條簡單語句(一般是能編譯成四條以內的指令)時,需要特別注意條件執行的情況。因為設計條件執行特性的初衷是保證流水線的完整性,這種跳轉位址只有幾個位元組的場景很容易被編譯成條件執行。
it指令用於根據特定條件來執行緊隨其後的1~4條指令,其格式為: it[x[y[z]]] 。其中x、y、z分別是執行第
二、三、四條指令的條件,可取的值為t(then)或e(else),對應於條件的成立和不成立。稱為條件字段,可取的值有:
條件字尾
標誌暫存器
含義eq
z == 1
等於ne
z == 0
不等於cs/hs
c == 1
無符號大於或相同
cc/lo
c == 0
無符號小於
min == 1
負數pl
n == 0
整數或零
vsv == 1
溢位vc
v == 0
無溢位hi
c == 1 && z == 0
無符號大於
lsc == 1 || z == 0
無符號小於或相同
gen == v
有符號大於或等於
ltn != v
有符號小於
gtz == 0 && n == v
有符號大於
lez == 1 || n != v
有符號小於或等於
al任何
始終。不可用於b中
看下面這個例子,意思是,當條件「eq」符合時,執行指令1、3、4的mov操作,否則執行指令2的mov操作。
itett
eq
moveqr0,
#1;//指令1
movner0,
#0;//指令2
moveqr1,
#0;//指令3
moveqr2,
#0;//指令4
此外,it指令還有一些限制,如:
不允許在 it 塊中使用下面的指令:除以下兩種情況外,均不允許跳進或跳出 it 塊:①it 塊的最後一條指令可為無條件跳轉指令(it指令會讓其變為條件跳轉)。 ②異常處理/恢復
**:
arm指令 ldr指令
ldr指令ldr作為指令 偽指令在arm彙編中。ldr指令格式 ldr 目的暫存器,儲存器位址 ldr r0,r1 將儲存器位址為r1的字資料讀入暫存器r0。ldr r0,r1,r2 將儲存器位址為r1 r2的字資料讀入暫存器r0。ldr r0,r1,8 將儲存器位址為r1 8的字資料讀入暫存器r0...
arm中的飽和指令
armv6 及更高版本中推出了飽和指令 ssat 和 usat,ssat16 和 usat16 有符號飽和到任何位位置和無符號飽和到任何位位置,可選擇在飽和前進行移位。ssat可將有符號值飽和到有符號範圍內。usat可將有符號值飽和到無符號範圍內。語法 oprd,sat,rm其中 op 是ssat或...
ARM中的STM LDM指令
stm ldm是批量傳輸資料的指令,這裡要說明的是 15 0 register list代表了16個暫存器,傳輸資料的時候r15始終是最後傳輸的,按照從r0到r15的順序,r15始終在高位址。遞增傳輸倒好理解,關鍵是遞減傳輸,2440的datasheet令我費解,看看datasheet裡的一張圖 假...