ARM彙編(基於樹莓派3B)2

控制程序流

無條件跳轉

B label :最大允許跳32MB範圍

關於CPSR

在這裏插入圖片描述
條件標誌位:
Negative(負數標誌位): N is 1 if the signed value is negative andcleared if the result is positive or 0.
Zero(零標誌位): Is set if the result is 0; this usually denotes an equal result from a comparison. If the result is non-zero, this flag is cleared.
Carry(進位標誌位): For addition type operations, this flag is set if the result produces an overflow. For subtraction type operation, this flag is set if the result requires a borrow. Also, it’s used in shifting to hold the last bit that is shifted out.
• OVerflow(溢出標誌位): For addition and subtraction, this flag is set if a signed overflow occurred. NOTE: Some instructions may specifically set oVerflow to flag an error condition.

中斷標誌位:
I: When set, disables IRQ interrupts(關閉IRQ中斷)
F: When set, disables FIQ interrupts(關閉FIQ中斷)
A: When set, disables imprecise aborts (關閉不精確的中止?)

指令集標誌:
Thumb: 16-bit compact instructions(16位緊湊指令)
Jazelle: Obsolete mode for directly executing Java bytecodes(直接執行Java字節碼的過時的模式)

其它標誌位:
Q: This flag is set to indicate underflow and/or saturation.(設置該標誌以指示下溢和/或飽和度)
GE: These flags control the Greater than or Equal behavior in SIMD instructions.
E: Is a flag that controls the “endianness” for data handling.(控制數據存儲使用的大/小端模式)

M is the processor mode such as user or supervisor(處理器模式,例如用戶模式、監視模式)

條件分支

一般的條件分支指令如下:
B{condition} label

{condition} Flags Meaning
EQ Z=1 相等
NE Z=0 不相等
CS或HS C=1 無符號>=
CC或LO C=0 無符號<
MI N=1 負數
PL N=0 正數或0
VS V=1 溢出
VC V=0 無溢出
HI C=1且Z=0 無符號>
LS C=0且Z=1 無符號<=
GE N=V 有符號>=
LT N!=V 有符號<
GT Z=0,N=V 有符號>
LE Z=1,N!=V 有符號<=
AL 任何時候 無條件執行

示例:
BEQ _start
當Z標誌位爲1時執行_start分支

Loops

for循環的彙編形式

@ 110
MOV R2, #1
loop: 
ADD R2, #1 @ I = I + 1
CMP R2, #10
BLE loop @ IF I <= 10 goto loop

while循環的彙編形式

loop: CMP R4, #5
BGE loopdone
... other statements in the loop body ...
B loop
loopdone: @program continues

If/Then/Else

IF R5 < 10 THEN
.... if statements ...
ELSE
... else statements ...
END IF

相應的彙編實現:

CMP R5, #10
BGE elseclause
... if statements ...
B endif
elseclause:
... else statements ...
endif: @ continue on after the /then/else ...

邏輯運算

AND{S} Rd, Rs, Operand2 與
EOR{S} Rd, Rs, Operand2 異或
ORR{S} Rd, Rs, Operand2 或
BIC{S} Rd, Rs, Operand2 (Rs AND NOT Operand2)

設計模式

在編寫彙編語言代碼時,很容易產生新的想法。例如,我們可以通過置寄存器的第十位爲1,然後將其右移直到寄存器爲零,來進行十次循環。這行得通,但是卻使程序閱讀變得困難。如果你退出程序並在下個月重新閱讀該程序,你有可能對它抓狂。
設計模式是常見編程模式的典型解決方案。如果採用一些關於如何執行循環和其他編程結構的標準設計模式,它將使你閱讀程序變得更加容易。
設計模式使編程更加高效,因爲在大多數情況下,可以僅使用一系列經過實踐檢驗的真實模式中的示例即可。
因此,我們以高級語言的模式實現了循環以及if / then / else。如果這樣做,它將使我們的程序更可靠,更快速地編寫。稍後,我們將研究如何使用匯編器中的宏來解決此問題。

將寄存器的內容存儲到內存

STRB R6, [R1]

分支程序的性能

在第1章“入門”中,我們提到了ARM32指令集是在指令管道中執行的。
一條指令需要三個時鐘週期來執行,每個週期需要1個時鐘週期。
1.將指令從內存加載到CPU。
2.解碼指令。
3.執行指令。
但是,CPU一次可以處理3條指令,每條指令執行不同的步驟,因此平均而言,每個時鐘週期我們執行一條指令。但是當我們有分支時會發生什麼呢?
執行分支時,我們已經解碼了下一條指令並將指令2加載到前面。當我們執行分支時,我們將前面已經完成的工作丟棄並重新開始。這意味着分支之後的指令將需要三個時鐘週期來執行。
如果在代碼中設置了很多分支,則可能會降低性能,可能會使程序減慢3倍。另一個問題是,如果使用很多分支進行編程,則會導致產生意大利麪條式代碼,即所有代碼行像一鍋意大利麪一樣糾結在一起,很難維護。

更多的比較指令

• CMN Rn, Operand2 :使用加法而不是減法
• TEQ Rn, Operand2 : 在Rn和Operand2之間執行按位異或運算。它根據結果更新CPSR。
• TST Rn, Operand2 : 在Rn和Operand2之間執行按位與運算。它根據結果更新CPSR。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章