ARM匯編指令中靈活的第二操作數(shù)

許多A32和T32的一般數(shù)據(jù)處理具有靈活的第二操作數(shù)(Operand2)。比如下面MOV這條指令:
MOV{S}{cond} Rd, Operand2

那么Operand2可以是什么。Operand2可以有下面兩種形式:

  • 常量(取值范圍是受限的)
  • 寄存器(可以對其進行移位)

Operand2是一個常量

Operand2作為常量的語法格式

語法格式:
#constant
constant可以是一個表達式,其計算結(jié)果應(yīng)為一個數(shù)值。

  • 在A32指令中,constant可以通過對一個8位值的數(shù)旋轉(zhuǎn)右移偶數(shù)個位(32位范圍內(nèi)的)來產(chǎn)生。

例子:
mov r1,#0x00110000

如果是下面這樣,armasm編譯器會報錯,不能用0-255和一個旋轉(zhuǎn)來表示
mov r1,#0x00110011

  • 對T32指令則有所不同,有下面四種方式可用的constant:

    • 形如0x00XY00XY的常量
    • 形如0xXY00XY00的常量
    • 形如0xXYXYXYXY的常量
    • 對一個8位值左移任意個位數(shù)(32位范圍內(nèi)的)

備注:其中X和Y代表的是16進制的數(shù)字。當然有少數(shù)的指令能擁有的值的范圍比這更廣。

當Operand2和MOVS, MVNS, ANDS, ORRS, ORNS, EORS, BICS, TEQ/TST這些指令一起使用時,如果常量的值大于255并且可以通過移位一個8位值來產(chǎn)生的話,進位標志會被更新為常量的bit[31]。當然如果常量是其他值的話,則不會對進位標志造成影響。

  • 指令替代
    如果Operand2并不是上面討論的有效值,但是它的邏輯反或者邏輯負是上面討論的有效值的話,則匯編器會根據(jù)該指令產(chǎn)生一條等效的指令,對該變量取反或者取負。

比如對下面這條指令
CMP Rd, #0xFFFFFFFE

匯編器可能會產(chǎn)生一條等效的指令如下:
CMN Rd, #0x2
你可以通過把反匯編代碼和源碼進行比較來確認這一點。

Operand2是一個帶可選移位的寄存器

語法格式:
Rm {, shift}
Rm保存著第二個操作數(shù)的數(shù)據(jù)。
shift是可選的,基于常量或者寄存器控制的移位位數(shù),其格式如下:

  • ASR #n; 1 ≤ n ≤ 32
  • LSL #n; 1 ≤ n ≤ 31
  • LSR #n; 1 ≤ n ≤ 32
  • ROR #n; 1 ≤ n ≤ 31
  • -;等價于LSL #0表示不移位
  • RRX
  • type Rs; type是ASR, LSL, LSR, ROR中的一個。Rs只用到Rs最低的那個字節(jié)來提供移位位數(shù)。

備注:type Rs格式只支持A32的指令集。同時移位完的結(jié)果并不會寫回Rm。對某些指令對寄存器進行移位操作可能會更新進位標志(carry flag)。

移位操作

上面介紹了Operand2的移位操作,Operand2是嵌于指令進行使用的。當然移位操作也有單獨的指令進行直接移位操作比如ASR, LSR, LSL, ROR, RRX等這些單獨指令。這兩種移位操作的效果是一樣的,下面分別對這5種移位操作進行介紹。

ASR

ASR(Arithmetic shift right),算術(shù)右移或者可以說是帶符號位的右移(符號位是bit[31])。ASR #n操作可以對寄存器的內(nèi)容進行算術(shù)右移n位,左邊被移走的n位用寄存器的符號位bit[31]進行填充,如圖13-1。

不管是單獨的ASRS指令或者和Operand2(ASR #n)進行配合使用的MOVS, MVNS, ANDS,ORRS, ORNS, EORS, BICS, TEQ , TST這些指令,進位標志會根據(jù)寄存器Rm最后一位被移除掉的位的值bit[n-1]進行更新。比如下面ASR #3的移位示意圖,bit[2]被更新到進位標志中。


image.png

備注:當32 <= n,如果需要更新進位標志那么進位標志=bit[31],并且結(jié)果中的所有位都被設(shè)置為bit[31]

例子:
MOV R1,#0X80000001
ASR R0,R1,#3; R0 = (signed)R1>> 3

LSR

LSR(Logical shift right),邏輯右移或者說是無符號的右移。LSR #n操作可以對寄存器的內(nèi)容進行邏輯右移n位,左邊被移走的n位全部被清零,如圖13-2。

不管是單獨的LSRS指令或者和Operand2(LSR #n)進行配合使用的MOVS, MVNS, ANDS,ORRS, ORNS, EORS, BICS, TEQ , TST這些指令,進位標志會根據(jù)寄存器Rm最后一位被移除掉的位的值bit[n-1]進行更新。比如下面LSR #3的移位示意圖,bit[2]被更新到進位標志中。


image.png

備注:當33 <= n,如果需要更新進位標志那么進位標志位為0。當32 <= n結(jié)果中的所有位都被設(shè)置為0。

例子:
MOV R1,#0X80000001
LSR R0,R1,#3; R0 = (unsigned)R1>> 3

LSL

LSL(Logical shift left),邏輯左移。LSL #n操作可以對寄存器的內(nèi)容進行邏輯左移n位,右邊被移走的n位全部被清零,如圖13-3。

不管是單獨的LSLS指令或者和Operand2(LSL #n)進行配合使用的MOVS, MVNS,ANDS, ORRS, ORNS, EORS, BICS, TEQ, TST這些指令,進位標志會根據(jù)寄存器Rm最后一位被移除掉的位的值bit[32-n]進行更新。比如下面LSL #3的移位示意圖,bit[29]被更新到進位標志中。

image.png

備注:當33 <= n,如果需要更新進位標志那么進位標志位為0。當32 <= n結(jié)果中的所有位都被設(shè)置為0。

例子:
MOV R1,#0X000000ff
LSLS R0,R1,#3

ROR

ROR(Rotate right),循環(huán)右移。ROR #n操作可以把寄存器內(nèi)容的最右邊移出的n位被放到最左邊空出來的n位,如圖13-4。

不管是單獨的RORS指令或者和Operand2(ROR #n)進行配合使用的MOVS,MVNS,ANDS,ORRS, ORNS, EORS, BICS, TEQ, TST這些指令,進位標志會根據(jù)寄存器Rm最后一位被移除掉的位的值bit[n-1]進行更新。比如下面ROR #3的移位示意圖,bit[2]被更新到進位標志中。

image.png

備注:n=32時,結(jié)果和最初的Rm值是一樣的,如果進位標志有需要更新那么進位標志=bit[31]。如果32 < n,那么n和n-32其操作的結(jié)果是一樣的。

例子:
MOV R1,#0X000000ff
ROR R0,R1,#3;

RRX

RRX(Rotate right with extend),帶擴展的循環(huán)右移。RRX參與循環(huán)右移的總共有33位,即32位的Rm+進位標志位。但是RRX只按順序循環(huán)右移一位,也就是bit[0]移動到進位標志位,進位標志位循環(huán)移動到bit[31],其他位按順序右移一位,如圖13-5所示。

不管是單獨的RRXS指令或者和Operand2(RRX)進行配合使用的MOVS, MVNS, ANDS,ORRS, ORNS, EORS, BICS, TEQ, TST這些指令,進位標志會根據(jù)寄存器Rm bit[0]進行更新。

image.png

例子:
MOV R1,#0X000000ff
RRXS R0,R1


參考資料
【1】DUI0801I_armasm_user_guide
【2】ARM Development Tools

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容