Arm處理器是基于精簡指令集計算機(RISC)原理設計的,指令集和相關譯碼機制較為簡單,具有32位Arm指令集和16位Thumb指令集,Arm指令集效率高,但是代碼密度低,而Thumb指令集具有更好的代碼密度,卻仍然保持Arm的大多數性能上的優勢,它是Arm指令集的子集。所有Arm指令都是可以有條件執行的,而Thumb指令僅有一條指令具備條件執行功能。Arm程序和Thumb程序可相互調用,相互之間的狀態切換開銷幾乎為零。
Cortex-M0處理器基于ARMv6-M架構,是一款功耗和性能較為均衡的處理器。Cortex-M0只支持56條指令的小指令集,其中大部分指令是16位指令。
Arm Cortex-M 指令集對比:
1. 指令集
1.1 在處理器內移動數據
MOV,;RmandRncanbehighorlowregisters. MOVS, MOVS,#immed8;8位立即數值 MRS, MSR,
1.2 存儲器訪問
確保訪問的內存地址是對齊的,這一點很重要。在ARMv6-M架構(包括Cortex-M0和Cortex-M0處理器)上不支持非對齊傳輸。任何未對齊內存訪問的嘗試都會導致HardFault異常。
LDR
1.3 棧空間訪問
PUSH{,,..} PUSH{,,..,LR} POP{,,..} POP{,,..,PC}
1.4 算數運算
ADD,;Rd=Rd+Rm.Rd,Rmcanbehighorlowregisters. ADDS,,;Rd=Rn+Rm SUBS,,;Rd=Rn–Rm ADDS,,#immed3;Rd=Rn+ZeroExtend(#immed3) SUBS,,#immed3;Rd=Rn–ZeroExtend(#immed3) ADDS,#immed8;Rd=Rd+ZeroExtend(#immed8) SUBS,#immed8;Rd=Rd–ZeroExtend(#immed8) ADCS,,;Rd=Rd+Rm+Carry SBCS,,;Rd=Rd–Rm–Borrow ADDSP,SP,#immed7;SP=SP+ZeroExtend(#immed7<<2) SUB??SP,?SP,?#immed7?????;?SP?=?SP?–?ZeroExtend(#immed7<<2) ADD??SP,?;SP=SP+Rm.Rmcanbehighorlowregister. ADD,SP,;Rd=Rd+SP.Rdcanbehighorlowregister. ADD,SP,#immed8;Rd=SP+ZeroExtend(#immed8<<2) ADD??,PC,#immed8;Rd=(PC[31:2]<<2)?+?ZeroExtend(#immed8<<2) ADR??,
1.5 邏輯運算
ANDS,,;Rd=AND(Rd,Rm) ORRS,,;Rd=OR(Rd,Rm) EORS,,;Rd=XOR(Rd,Rm) BICS,,;Rd=AND(Rd,NOT(Rm)) MVNS,;Rd=NOT(Rm) TST,;AND(Rn,Rm)
1.6 移位和循環操作
ASRS,,#immed5;Rd=Rm>>immed5 LSLS,,#immed5;Rd=Rm<<#immed5 LSRS?,,#immed5;Rd=Rm>>#immed5ASRS,,;Rd=Rd>>Rm LSLS,,;Rd=Rd<,,;Rd=Rd>>RmRORS,,;Rd=RdrotaterightbyRmbits //Rotate_Left(Data,offset)=Rotate_Right(Data,(32-offset))
1.7 展開和順序反轉操作
這些反向指令通常用于在小端和之間轉換數據大整數。
REV,;Byte-ReverseWord //Rd={Rm[7:0],Rm[15:8],Rm[23:16],Rm[31:24]} REV16,;Byte-ReversePackedHalfWord //Rd={Rm[23:16],Rm[31:24],Rm[7:0],Rm[15:8]} REVSH,;Byte-ReverseSignedHalfWord //Rd=SignExtend({Rm[7:0],Rm[15:8]})
1.8 擴展操作
它們通常用于數據類型轉換。
SXTB,;SignedExtendedByte //Rd=SignExtend(Rm[7:0]) SXTH,;SignedExtendedHalfWord //Rd=SignExtend(Rm[15:0]) UXTB,;UnsignedExtendedByte //Rd=ZeroExtend(Rm[7:0]) UXTH,;UnsignedExtendedHalfWord //Rd=ZeroExtend(Rm[15:0])
1.9 程序流控制
B
條件轉移指令B
1.10 內存屏障指令
在Cortex-M0和Cortex-M0處理器上支持內存屏障指令,從而在Cortex-M處理器和其他ARM處理器家族中提供更好的兼容性。
//數據內存屏障,確保所有內存訪問都完成 //在新的內存訪問被提交之前。
DMB
//數據同步屏障,確保所有的內存訪問都完成 //在執行下一條指令之前。
DSB
//指令同步障礙,刷新管道和 //確保之前所有的指令都已完成 //在執行新指令之前。
ISB
1.11 異常相關指令
SVC ; Supervisor call CPSIE I ; Enable Interrupt (Clearing PRIMASK) CPSID I ; Disable Interrupt (Setting PRIMASK)
1.12 睡眠模式功能相關說明
//等待中斷,停止程序執行,直到一個中斷到達, //如果處理器進入調試狀態。
WFI
//等待事件,如果設置了內部事件寄存器,則清除 //內部事件注冊和繼續執行。 //停止程序執行,直到事件(如中斷)到達 //如果處理器進入調試狀態。
WFE
//發送事件,設置本地事件寄存器并發送一個事件脈沖 //多處理器系統中的其他微處理器。
SEV
1.13 其他說明
NOP;NoOperation BKPT;Breakpoint YIELD;ExecuteasNOPontheCortex-M0processor
2. 指令說明
2.1 可訪問high registers的指令
絕大部分指令只能訪問low registers,也就是只能訪問R0~R7寄存器??梢栽L問high registers的指令只有兩條,這兩條指令都不更新APSR,指令沒有S后綴。
MOV,;RmandRncanbehighorlowregisters. ADD,;Rd=Rd+Rm.Rd,Rmcanbehighorlowregisters.
其它兩條和SP加法有關的可以訪問high registers的指令其本質是ADD指令。
ADDSP, ADD,SP,
2.2 分配臨時變量的指令
函數內的臨時變量分配到堆棧,進入函數給臨時變量分配空間時使用SUB指令。
SUB SP, SP, #immed7 ; SP = SP – ZeroExtend(#immed7<<2)
退出函數釋放臨時變量空間時使用ADD指令。
ADD SP, SP, #immed7 ; SP = SP + ZeroExtend(#immed7<<2)
上面兩條指令的立即數只有7位,最多可以增減SP指針127個字空間,如果超過127個字,使用這條指令:
ADD SP, ; SP = SP + Rm. Rm can be high or low register.
只有ADD指令,沒有SUB指令,如果需要SUB,那么給Rm賦值負數即可。
2.3 取臨時變量地址的指令
在堆棧分配了臨時變量空間后,總要取得臨時變量的地址才能做進一步的操作。
ADD , SP, #immed8 ; Rd = SP + ZeroExtend(#immed8<<2)
立即數不夠,可以用寄存器。
ADD , SP, ; Rd = Rd + SP. Rd can be high or low register.
2.4 RSBS指令
RSBS , , #0 ; Rd = 0 – Rm, Reverse Subtract (negative)
這是倒過來的減法,常量減去寄存器值,而且常量只能是0。所以這條指令實質上就是一條取負數指令。
Rd = 0 - Rm 等價于:Rd = -Rm Rd 寄存器值等于負的 Rm 寄存器值。
評論